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]; 634ddd07fcSJed Brown 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 */ 714ddd07fcSJed Brown PetscInt relaxtype[3]; 7239accc25SStefano Zampini PetscReal relaxweight; 7339accc25SStefano Zampini PetscReal outerrelaxweight; 744ddd07fcSJed Brown PetscInt relaxorder; 7539accc25SStefano Zampini PetscReal truncfactor; 76ace3abfcSBarry Smith PetscBool applyrichardson; 774ddd07fcSJed Brown PetscInt pmax; 784ddd07fcSJed Brown PetscInt interptype; 79589dcaf0SStefano Zampini PetscInt maxc; 80589dcaf0SStefano Zampini PetscInt minc; 81db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 82db6f9c32SMark Adams char *spgemm_type; // this is a global hypre parameter but is closely associated with BoomerAMG 83db6f9c32SMark Adams #endif 846ea7df73SStefano Zampini /* GPU */ 856ea7df73SStefano Zampini PetscBool keeptranspose; 866ea7df73SStefano Zampini PetscInt rap2; 876ea7df73SStefano Zampini 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; 976ea7df73SStefano Zampini 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 258d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_HYPRE(PC pc) 259d71ae5a4SJacob Faibussowitsch { 26016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 26149a781f5SStefano Zampini Mat_HYPRE *hjac; 26216d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 26316d9e3a6SLisandro Dalcin HYPRE_ParVector bv, xv; 26449a781f5SStefano Zampini PetscBool ishypre; 26516d9e3a6SLisandro Dalcin 26616d9e3a6SLisandro Dalcin PetscFunctionBegin; 2670df1829cSStefano Zampini /* default type is boomerAMG */ 26848a46eb9SPierre Jolivet if (!jac->hypre_type) PetscCall(PCHYPRESetType(pc, "boomeramg")); 2695f5c5b43SBarry Smith 2700df1829cSStefano Zampini /* get hypre matrix */ 2710df1829cSStefano Zampini if (pc->flag == DIFFERENT_NONZERO_PATTERN) PetscCall(MatDestroy(&jac->hpmat)); 2729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRE, &ishypre)); 27349a781f5SStefano Zampini if (!ishypre) { 274*e6519f9fSJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) && PETSC_PKG_HYPRE_VERSION_LE(2, 30, 0) 2750df1829cSStefano Zampini /* Temporary fix since we do not support MAT_REUSE_MATRIX with HYPRE device */ 2760df1829cSStefano Zampini PetscBool iscuda, iship, iskokkos; 2770df1829cSStefano Zampini 2780df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iscuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, "")); 2790df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iship, MATSEQAIJHIPSPARSE, MATMPIAIJHIPSPARSE, "")); 2800df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iskokkos, MATSEQAIJKOKKOS, MATMPIAIJKOKKOS, "")); 2810df1829cSStefano Zampini if (iscuda || iship || iskokkos) PetscCall(MatDestroy(&jac->hpmat)); 2820df1829cSStefano Zampini #endif 2830df1829cSStefano Zampini PetscCall(MatConvert(pc->pmat, MATHYPRE, jac->hpmat ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX, &jac->hpmat)); 28449a781f5SStefano Zampini } else { 2859566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc->pmat)); 2869566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 28749a781f5SStefano Zampini jac->hpmat = pc->pmat; 28816d9e3a6SLisandro Dalcin } 2890df1829cSStefano Zampini 2906ea7df73SStefano Zampini /* allow debug */ 2919566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(jac->hpmat, NULL, "-pc_hypre_mat_view")); 292f4f49eeaSPierre Jolivet hjac = (Mat_HYPRE *)jac->hpmat->data; 2935f5c5b43SBarry Smith 29416d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 29516d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 2965272c319SBarry Smith MatNullSpace mnull; 2975272c319SBarry Smith PetscBool has_const; 29849a781f5SStefano Zampini PetscInt bs, nvec, i; 2995272c319SBarry Smith const Vec *vecs; 3005272c319SBarry Smith 3019566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat, &bs)); 302792fecdfSBarry Smith if (bs > 1) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 3039566063dSJacob Faibussowitsch PetscCall(MatGetNearNullSpace(pc->mat, &mnull)); 3045272c319SBarry Smith if (mnull) { 3059566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 3069566063dSJacob Faibussowitsch PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs)); 3079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->hmnull)); 3089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->phmnull)); 3095272c319SBarry Smith for (i = 0; i < nvec; i++) { 3109566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map, &jac->hmnull[i])); 3119566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(vecs[i], jac->hmnull[i])); 312792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[i]->ij, (void **)&jac->phmnull[i]); 3135272c319SBarry Smith } 3145272c319SBarry Smith if (has_const) { 3159566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(pc->pmat, &jac->hmnull_constant, NULL)); 3169566063dSJacob Faibussowitsch PetscCall(VecSet(jac->hmnull_constant, 1)); 3179566063dSJacob Faibussowitsch PetscCall(VecNormalize(jac->hmnull_constant, NULL)); 3189566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map, &jac->hmnull[nvec])); 3199566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant, jac->hmnull[nvec])); 320792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[nvec]->ij, (void **)&jac->phmnull[nvec]); 3215272c319SBarry Smith nvec++; 3225272c319SBarry Smith } 323792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVectors, jac->hsolver, nvec, jac->phmnull); 3245272c319SBarry Smith jac->n_hmnull = nvec; 3255272c319SBarry Smith } 3264cb006feSStefano Zampini } 327863406b8SStefano Zampini 3284cb006feSStefano Zampini /* special case for AMS */ 3294cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 3305ac14e1cSStefano Zampini Mat_HYPRE *hm; 3315ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 3326bf688a0SCe Qin if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 333f1580f4eSBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE AMS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the edge constant vectors via PCHYPRESetEdgeConstantVectors() or the interpolation matrix via PCHYPRESetInterpolations()"); 3346bf688a0SCe Qin } 33548a46eb9SPierre Jolivet if (jac->dim) PetscCallExternal(HYPRE_AMSSetDimension, jac->hsolver, jac->dim); 3365ac14e1cSStefano Zampini if (jac->constants[0]) { 3375ac14e1cSStefano Zampini HYPRE_ParVector ozz, zoz, zzo = NULL; 338792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[0]->ij, (void **)(&ozz)); 339792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[1]->ij, (void **)(&zoz)); 34048a46eb9SPierre Jolivet if (jac->constants[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[2]->ij, (void **)(&zzo)); 341792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetEdgeConstantVectors, jac->hsolver, ozz, zoz, zzo); 3425ac14e1cSStefano Zampini } 3435ac14e1cSStefano Zampini if (jac->coords[0]) { 3445ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3455ac14e1cSStefano Zampini coords[0] = NULL; 3465ac14e1cSStefano Zampini coords[1] = NULL; 3475ac14e1cSStefano Zampini coords[2] = NULL; 348792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 349792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 350792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 351792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 3525ac14e1cSStefano Zampini } 3535f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 354f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->G->data; 355792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 356792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDiscreteGradient, jac->hsolver, parcsr); 3575ac14e1cSStefano Zampini if (jac->alpha_Poisson) { 358f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->alpha_Poisson->data; 359792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 360792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaPoissonMatrix, jac->hsolver, parcsr); 3615ac14e1cSStefano Zampini } 3625ac14e1cSStefano Zampini if (jac->ams_beta_is_zero) { 363792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, NULL); 3645ac14e1cSStefano Zampini } else if (jac->beta_Poisson) { 365f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->beta_Poisson->data; 366792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 367792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, parcsr); 368be14dc20SKerry Key } else if (jac->ams_beta_is_zero_part) { 369be14dc20SKerry Key if (jac->interior) { 370be14dc20SKerry Key HYPRE_ParVector interior = NULL; 371be14dc20SKerry Key PetscCallExternal(HYPRE_IJVectorGetObject, jac->interior->ij, (void **)(&interior)); 372be14dc20SKerry Key PetscCallExternal(HYPRE_AMSSetInteriorNodes, jac->hsolver, interior); 373be14dc20SKerry Key } else { 374be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 375be14dc20SKerry Key } 3765ac14e1cSStefano Zampini } 3776bf688a0SCe Qin if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) { 3786bf688a0SCe Qin PetscInt i; 3796bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3806bf688a0SCe Qin if (jac->ND_PiFull) { 381f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_PiFull->data; 382792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 3836bf688a0SCe Qin } else { 3846bf688a0SCe Qin nd_parcsrfull = NULL; 3856bf688a0SCe Qin } 3866bf688a0SCe Qin for (i = 0; i < 3; ++i) { 3876bf688a0SCe Qin if (jac->ND_Pi[i]) { 388f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_Pi[i]->data; 389792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 3906bf688a0SCe Qin } else { 3916bf688a0SCe Qin nd_parcsr[i] = NULL; 3926bf688a0SCe Qin } 3936bf688a0SCe Qin } 394792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetInterpolations, jac->hsolver, nd_parcsrfull, nd_parcsr[0], nd_parcsr[1], nd_parcsr[2]); 3956bf688a0SCe Qin } 3964cb006feSStefano Zampini } 397863406b8SStefano Zampini /* special case for ADS */ 398863406b8SStefano Zampini if (jac->setup == HYPRE_ADSSetup) { 3995ac14e1cSStefano Zampini Mat_HYPRE *hm; 4005ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 4016bf688a0SCe 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])))) { 4026bf688a0SCe Qin SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations"); 4039371c9d4SSatish 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"); 4045f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 4055f80ce2aSJacob Faibussowitsch PetscCheck(jac->C, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient"); 4065ac14e1cSStefano Zampini if (jac->coords[0]) { 4075ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 4085ac14e1cSStefano Zampini coords[0] = NULL; 4095ac14e1cSStefano Zampini coords[1] = NULL; 4105ac14e1cSStefano Zampini coords[2] = NULL; 411792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 412792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 413792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 414792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 4155ac14e1cSStefano Zampini } 416f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->G->data; 417792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 418792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteGradient, jac->hsolver, parcsr); 419f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->C->data; 420792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 421792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteCurl, jac->hsolver, parcsr); 4226bf688a0SCe Qin if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 4236bf688a0SCe Qin PetscInt i; 4246bf688a0SCe Qin HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3]; 4256bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 4266bf688a0SCe Qin if (jac->RT_PiFull) { 427f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->RT_PiFull->data; 428792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsrfull)); 4296bf688a0SCe Qin } else { 4306bf688a0SCe Qin rt_parcsrfull = NULL; 4316bf688a0SCe Qin } 4326bf688a0SCe Qin for (i = 0; i < 3; ++i) { 4336bf688a0SCe Qin if (jac->RT_Pi[i]) { 434f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->RT_Pi[i]->data; 435792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsr[i])); 4366bf688a0SCe Qin } else { 4376bf688a0SCe Qin rt_parcsr[i] = NULL; 4386bf688a0SCe Qin } 4396bf688a0SCe Qin } 4406bf688a0SCe Qin if (jac->ND_PiFull) { 441f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_PiFull->data; 442792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 4436bf688a0SCe Qin } else { 4446bf688a0SCe Qin nd_parcsrfull = NULL; 4456bf688a0SCe Qin } 4466bf688a0SCe Qin for (i = 0; i < 3; ++i) { 4476bf688a0SCe Qin if (jac->ND_Pi[i]) { 448f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_Pi[i]->data; 449792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 4506bf688a0SCe Qin } else { 4516bf688a0SCe Qin nd_parcsr[i] = NULL; 4526bf688a0SCe Qin } 4536bf688a0SCe Qin } 454792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetInterpolations, jac->hsolver, rt_parcsrfull, rt_parcsr[0], rt_parcsr[1], rt_parcsr[2], nd_parcsrfull, nd_parcsr[0], nd_parcsr[1], nd_parcsr[2]); 4556bf688a0SCe Qin } 456863406b8SStefano Zampini } 457792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 458792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&bv); 459792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&xv); 46097c1e3cbSStefano Zampini PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 461792fecdfSBarry Smith PetscCallExternal(jac->setup, jac->hsolver, hmat, bv, xv); 46297c1e3cbSStefano Zampini PetscCall(PetscFPTrapPop()); 4633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 46416d9e3a6SLisandro Dalcin } 46516d9e3a6SLisandro Dalcin 466d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_HYPRE(PC pc, Vec b, Vec x) 467d71ae5a4SJacob Faibussowitsch { 46816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 469f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 47016d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 47116d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 47216d9e3a6SLisandro Dalcin 47316d9e3a6SLisandro Dalcin PetscFunctionBegin; 4749566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 4759566063dSJacob Faibussowitsch if (!jac->applyrichardson) PetscCall(VecSet(x, 0.0)); 4769566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b, b)); 4779566063dSJacob Faibussowitsch if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x, x)); 4789566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x, x)); 479792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 480792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 481792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 4829371c9d4SSatish Balay PetscStackCallExternalVoid( 4839371c9d4SSatish Balay "Hypre solve", do { 4845f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = (*jac->solve)(jac->hsolver, hmat, jbv, jxv); 4855f80ce2aSJacob Faibussowitsch if (hierr) { 4865f80ce2aSJacob Faibussowitsch PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 48785245615SPierre Jolivet HYPRE_ClearAllErrors(); 4885f80ce2aSJacob Faibussowitsch } 4895f80ce2aSJacob Faibussowitsch } while (0)); 49016d9e3a6SLisandro Dalcin 49148a46eb9SPierre Jolivet if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) PetscCallExternal(HYPRE_AMSProjectOutGradients, jac->hsolver, jxv); 4929566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 4939566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 4943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49516d9e3a6SLisandro Dalcin } 49616d9e3a6SLisandro Dalcin 49785245615SPierre Jolivet static PetscErrorCode PCMatApply_HYPRE_BoomerAMG(PC pc, Mat B, Mat X) 49885245615SPierre Jolivet { 49985245615SPierre Jolivet PC_HYPRE *jac = (PC_HYPRE *)pc->data; 500f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 50185245615SPierre Jolivet hypre_ParCSRMatrix *par_matrix; 50285245615SPierre Jolivet HYPRE_ParVector hb, hx; 50385245615SPierre Jolivet const PetscScalar *b; 50485245615SPierre Jolivet PetscScalar *x; 50585245615SPierre Jolivet PetscInt m, N, lda; 50685245615SPierre Jolivet hypre_Vector *x_local; 50785245615SPierre Jolivet PetscMemType type; 50885245615SPierre Jolivet 50985245615SPierre Jolivet PetscFunctionBegin; 51085245615SPierre Jolivet PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 51185245615SPierre Jolivet PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&par_matrix); 51285245615SPierre Jolivet PetscCall(MatGetLocalSize(B, &m, NULL)); 51385245615SPierre Jolivet PetscCall(MatGetSize(B, NULL, &N)); 51485245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hb); 51585245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hx); 51685245615SPierre Jolivet PetscCall(MatZeroEntries(X)); 51785245615SPierre Jolivet PetscCall(MatDenseGetArrayReadAndMemType(B, &b, &type)); 51885245615SPierre Jolivet PetscCall(MatDenseGetLDA(B, &lda)); 51985245615SPierre 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); 52085245615SPierre Jolivet PetscCall(MatDenseGetLDA(X, &lda)); 52185245615SPierre 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); 52285245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hb); 52385245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 52485245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)b; 52585245615SPierre Jolivet PetscCall(MatDenseGetArrayWriteAndMemType(X, &x, NULL)); 52685245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hx); 52785245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 52885245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)x; 52985245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hb, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 53085245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hx, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 53185245615SPierre Jolivet PetscStackCallExternalVoid( 53285245615SPierre Jolivet "Hypre solve", do { 53385245615SPierre Jolivet HYPRE_Int hierr = (*jac->solve)(jac->hsolver, par_matrix, hb, hx); 53485245615SPierre Jolivet if (hierr) { 53585245615SPierre Jolivet PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 53685245615SPierre Jolivet HYPRE_ClearAllErrors(); 53785245615SPierre Jolivet } 53885245615SPierre Jolivet } while (0)); 53985245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hb); 54085245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hx); 54185245615SPierre Jolivet PetscCall(MatDenseRestoreArrayReadAndMemType(B, &b)); 54285245615SPierre Jolivet PetscCall(MatDenseRestoreArrayWriteAndMemType(X, &x)); 54385245615SPierre Jolivet PetscFunctionReturn(PETSC_SUCCESS); 54485245615SPierre Jolivet } 54585245615SPierre Jolivet 546d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_HYPRE(PC pc) 547d71ae5a4SJacob Faibussowitsch { 5488695de01SBarry Smith PC_HYPRE *jac = (PC_HYPRE *)pc->data; 5498695de01SBarry Smith 5508695de01SBarry Smith PetscFunctionBegin; 5519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 5529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 5539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 5549566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 5559566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 5569566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 5579566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[0])); 5589566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[1])); 5599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[2])); 5609566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 5619566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[0])); 5629566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[1])); 5639566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[2])); 5649566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 5659566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 5669566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 5679566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 5689566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 5699566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 570be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 5719566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 5725ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 573be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 5745ac14e1cSStefano Zampini jac->dim = 0; 5753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5768695de01SBarry Smith } 5778695de01SBarry Smith 578d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_HYPRE(PC pc) 579d71ae5a4SJacob Faibussowitsch { 58016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 58116d9e3a6SLisandro Dalcin 58216d9e3a6SLisandro Dalcin PetscFunctionBegin; 5839566063dSJacob Faibussowitsch PetscCall(PCReset_HYPRE(pc)); 584792fecdfSBarry Smith if (jac->destroy) PetscCallExternal(jac->destroy, jac->hsolver); 5859566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 586db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 5879566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->spgemm_type)); 588db6f9c32SMark Adams #endif 5899566063dSJacob Faibussowitsch if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 5909566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 59116d9e3a6SLisandro Dalcin 5929566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc, 0)); 5939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", NULL)); 5949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", NULL)); 5959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", NULL)); 5969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", NULL)); 5979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", NULL)); 5989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetConstantEdgeVectors_C", NULL)); 5999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", NULL)); 6002e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", NULL)); 601be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", NULL)); 6029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", NULL)); 6039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", NULL)); 60442e5ec60SJeff-Hadley PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetCFMarkers_C", NULL)); 6059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", NULL)); 6069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", NULL)); 6072e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", NULL)); 6083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 60916d9e3a6SLisandro Dalcin } 61016d9e3a6SLisandro Dalcin 611d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc, PetscOptionItems *PetscOptionsObject) 612d71ae5a4SJacob Faibussowitsch { 61316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 614ace3abfcSBarry Smith PetscBool flag; 61516d9e3a6SLisandro Dalcin 61616d9e3a6SLisandro Dalcin PetscFunctionBegin; 617d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Pilut Options"); 6189566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter", "Number of iterations", "None", jac->maxiter, &jac->maxiter, &flag)); 619792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetMaxIter, jac->hsolver, jac->maxiter); 6209566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol", "Drop tolerance", "None", jac->tol, &jac->tol, &flag)); 621792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetDropTolerance, jac->hsolver, jac->tol); 6229566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize", "FactorRowSize", "None", jac->factorrowsize, &jac->factorrowsize, &flag)); 623792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetFactorRowSize, jac->hsolver, jac->factorrowsize); 624d0609cedSBarry Smith PetscOptionsHeadEnd(); 6253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62616d9e3a6SLisandro Dalcin } 62716d9e3a6SLisandro Dalcin 628d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Pilut(PC pc, PetscViewer viewer) 629d71ae5a4SJacob Faibussowitsch { 63016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 631ace3abfcSBarry Smith PetscBool iascii; 63216d9e3a6SLisandro Dalcin 63316d9e3a6SLisandro Dalcin PetscFunctionBegin; 6349566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 63516d9e3a6SLisandro Dalcin if (iascii) { 6369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Pilut preconditioning\n")); 63716d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 63863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum number of iterations %" PetscInt_FMT "\n", jac->maxiter)); 63916d9e3a6SLisandro Dalcin } else { 6409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default maximum number of iterations \n")); 64116d9e3a6SLisandro Dalcin } 64216d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 6439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->tol)); 64416d9e3a6SLisandro Dalcin } else { 6459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default drop tolerance \n")); 64616d9e3a6SLisandro Dalcin } 64716d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 64863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factor row size %" PetscInt_FMT "\n", jac->factorrowsize)); 64916d9e3a6SLisandro Dalcin } else { 6509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factor row size \n")); 65116d9e3a6SLisandro Dalcin } 65216d9e3a6SLisandro Dalcin } 6533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 65416d9e3a6SLisandro Dalcin } 65516d9e3a6SLisandro Dalcin 6563c61a47dSLukas static const char *HYPREILUType[] = { 6573c61a47dSLukas "Block-Jacobi-ILUk", "Block-Jacobi-ILUT", "", "", "", "", "", "", "", "", /* 0-9 */ 6583c61a47dSLukas "GMRES-ILUk", "GMRES-ILUT", "", "", "", "", "", "", "", "", /* 10-19 */ 6593c61a47dSLukas "NSH-ILUk", "NSH-ILUT", "", "", "", "", "", "", "", "", /* 20-29 */ 6603c61a47dSLukas "RAS-ILUk", "RAS-ILUT", "", "", "", "", "", "", "", "", /* 30-39 */ 6613c61a47dSLukas "ddPQ-GMRES-ILUk", "ddPQ-GMRES-ILUT", "", "", "", "", "", "", "", "", /* 40-49 */ 6623c61a47dSLukas "GMRES-ILU0" /* 50 */ 6633c61a47dSLukas }; 6643c61a47dSLukas 6653c61a47dSLukas static const char *HYPREILUIterSetup[] = {"default", "async-in-place", "async-explicit", "sync-explicit", "semisync-explicit"}; 6663c61a47dSLukas 6673c61a47dSLukas static PetscErrorCode PCSetFromOptions_HYPRE_ILU(PC pc, PetscOptionItems *PetscOptionsObject) 6683c61a47dSLukas { 6693c61a47dSLukas PC_HYPRE *jac = (PC_HYPRE *)pc->data; 6703c61a47dSLukas PetscBool flg; 6713c61a47dSLukas PetscInt indx; 6723c61a47dSLukas PetscReal tmpdbl; 6733c61a47dSLukas PetscBool tmp_truth; 6743c61a47dSLukas 6753c61a47dSLukas PetscFunctionBegin; 6763c61a47dSLukas PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ILU Options"); 6773c61a47dSLukas 6783c61a47dSLukas /* ILU: ILU Type */ 6793c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_ilu_type", "Choose ILU Type", "None", HYPREILUType, PETSC_STATIC_ARRAY_LENGTH(HYPREILUType), HYPREILUType[0], &indx, &flg)); 6803c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetType, jac->hsolver, indx); } 6813c61a47dSLukas 6823c61a47dSLukas /* ILU: ILU iterative setup type*/ 6833c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_ilu_iterative_setup_type", "Set ILU iterative setup type", "None", HYPREILUIterSetup, PETSC_STATIC_ARRAY_LENGTH(HYPREILUIterSetup), HYPREILUIterSetup[0], &indx, &flg)); 6843c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetIterativeSetupType, jac->hsolver, indx); } 6853c61a47dSLukas 6863c61a47dSLukas /* ILU: ILU iterative setup option*/ 6873c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_iterative_setup_option", "Set ILU iterative setup option", "None", 0, &indx, &flg)); 6883c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetIterativeSetupOption, jac->hsolver, indx); } 6893c61a47dSLukas 6903c61a47dSLukas /* ILU: ILU iterative setup maxiter */ 6913c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_iterative_setup_maxiter", "Set ILU iterative setup maximum iteration count", "None", 0, &indx, &flg)); 6923c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetIterativeSetupMaxIter, jac->hsolver, indx); } 6933c61a47dSLukas 6943c61a47dSLukas /* ILU: ILU iterative setup tolerance */ 6953c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_iterative_setup_tolerance", "Set ILU iterative setup tolerance", "None", 0, &tmpdbl, &flg)); 6963c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetIterativeSetupTolerance, jac->hsolver, tmpdbl); } 6973c61a47dSLukas 6983c61a47dSLukas /* ILU: ILU Print Level */ 6993c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_print_level", "Set ILU print level", "None", 0, &indx, &flg)); 7003c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetPrintLevel, jac->hsolver, indx); } 7013c61a47dSLukas 7023c61a47dSLukas /* ILU: Logging */ 7033c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_logging", "Set ILU logging level", "None", 0, &indx, &flg)); 7043c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetLogging, jac->hsolver, indx); } 7053c61a47dSLukas 7063c61a47dSLukas /* ILU: ILU Level */ 7073c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_level", "Set ILU level", "None", 0, &indx, &flg)); 7083c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetLevelOfFill, jac->hsolver, indx); } 7093c61a47dSLukas 7103c61a47dSLukas /* ILU: ILU Max NNZ per row */ 7113c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_max_nnz_per_row", "Set maximum NNZ per row", "None", 0, &indx, &flg)); 7123c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetMaxNnzPerRow, jac->hsolver, indx); } 7133c61a47dSLukas 7143c61a47dSLukas /* ILU: tolerance */ 7153c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_tol", "Tolerance for ILU", "None", 0, &tmpdbl, &flg)); 7163c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetTol, jac->hsolver, tmpdbl); } 7173c61a47dSLukas 7183c61a47dSLukas /* ILU: maximum iteration count */ 7193c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_maxiter", "Set ILU max iterations", "None", 0, &indx, &flg)); 7203c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetMaxIter, jac->hsolver, indx); } 7213c61a47dSLukas 7223c61a47dSLukas /* ILU: drop threshold */ 7233c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_drop_threshold", "Drop threshold for ILU", "None", 0, &tmpdbl, &flg)); 7243c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetDropThreshold, jac->hsolver, tmpdbl); } 7253c61a47dSLukas 7263c61a47dSLukas /* ILU: Triangular Solve */ 7273c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_ilu_tri_solve", "Enable triangular solve", "None", PETSC_FALSE, &tmp_truth, &flg)); 7283c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetTriSolve, jac->hsolver, tmp_truth); } 7293c61a47dSLukas 7303c61a47dSLukas /* ILU: Lower Jacobi iteration */ 7313c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_lower_jacobi_iters", "Set lower Jacobi iteration count", "None", 0, &indx, &flg)); 7323c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetLowerJacobiIters, jac->hsolver, indx); } 7333c61a47dSLukas 7343c61a47dSLukas /* ILU: Upper Jacobi iteration */ 7353c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_upper_jacobi_iters", "Set upper Jacobi iteration count", "None", 0, &indx, &flg)); 7363c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetUpperJacobiIters, jac->hsolver, indx); } 7373c61a47dSLukas 7383c61a47dSLukas /* ILU: local reordering */ 7393c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_ilu_local_reordering", "Enable local reordering", "None", PETSC_FALSE, &tmp_truth, &flg)); 7403c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetLocalReordering, jac->hsolver, tmp_truth); } 7413c61a47dSLukas 7423c61a47dSLukas PetscOptionsHeadEnd(); 7433c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 7443c61a47dSLukas } 7453c61a47dSLukas 7463c61a47dSLukas static PetscErrorCode PCView_HYPRE_ILU(PC pc, PetscViewer viewer) 7473c61a47dSLukas { 7483c61a47dSLukas PC_HYPRE *jac = (PC_HYPRE *)pc->data; 7493c61a47dSLukas hypre_ParILUData *ilu_data = (hypre_ParILUData *)jac->hsolver; 7503c61a47dSLukas PetscBool iascii; 7513c61a47dSLukas PetscInt indx; 7523c61a47dSLukas PetscReal tmpdbl; 7533c61a47dSLukas PetscReal *tmpdbl3; 7543c61a47dSLukas 7553c61a47dSLukas PetscFunctionBegin; 7563c61a47dSLukas PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 7573c61a47dSLukas if (iascii) { 7583c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ILU preconditioning\n")); 7593c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIluType", indx = hypre_ParILUDataIluType(ilu_data)); 7603c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU type %s (%" PetscInt_FMT ")\n", HYPREILUType[indx], indx)); 7613c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLfil", indx = hypre_ParILUDataLfil(ilu_data)); 7623c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU level %" PetscInt_FMT "\n", indx)); 7633c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataMaxIter", indx = hypre_ParILUDataMaxIter(ilu_data)); 7643c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max iterations %" PetscInt_FMT "\n", indx)); 7653c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataMaxRowNnz", indx = hypre_ParILUDataMaxRowNnz(ilu_data)); 7663c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max NNZ per row %" PetscInt_FMT "\n", indx)); 7673c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataTriSolve", indx = hypre_ParILUDataTriSolve(ilu_data)); 7683c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU triangular solve %" PetscInt_FMT "\n", indx)); 7693c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataTol", tmpdbl = hypre_ParILUDataTol(ilu_data)); 7703c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU tolerance %e\n", tmpdbl)); 7713c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataDroptol", tmpdbl3 = hypre_ParILUDataDroptol(ilu_data)); 7723c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU drop tolerance %e / %e / %e\n", tmpdbl3[0], tmpdbl3[1], tmpdbl3[2])); 7733c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataReorderingType", indx = hypre_ParILUDataReorderingType(ilu_data)); 7743c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU local reordering %" PetscInt_FMT "\n", indx)); 7753c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLowerJacobiIters", indx = hypre_ParILUDataLowerJacobiIters(ilu_data)); 7763c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU lower Jacobi iterations %" PetscInt_FMT "\n", indx)); 7773c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataUpperJacobiIters", indx = hypre_ParILUDataUpperJacobiIters(ilu_data)); 7783c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU upper Jacobi iterations %" PetscInt_FMT "\n", indx)); 7793c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataPrintLevel", indx = hypre_ParILUDataPrintLevel(ilu_data)); 7803c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU print level %" PetscInt_FMT "\n", indx)); 7813c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLogging", indx = hypre_ParILUDataLogging(ilu_data)); 7823c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU logging level %" PetscInt_FMT "\n", indx)); 7833c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupType", indx = hypre_ParILUDataIterativeSetupType(ilu_data)); 7843c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup type %s (%" PetscInt_FMT ")\n", HYPREILUIterSetup[indx], indx)); 7853c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupOption", indx = hypre_ParILUDataIterativeSetupOption(ilu_data)); 7863c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup option %" PetscInt_FMT "\n", indx)); 7873c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupMaxIter", indx = hypre_ParILUDataIterativeSetupMaxIter(ilu_data)); 7883c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup max iterations %" PetscInt_FMT "\n", indx)); 7893c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupTolerance", tmpdbl = hypre_ParILUDataIterativeSetupTolerance(ilu_data)); 7903c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup tolerance %e\n", tmpdbl)); 7913c61a47dSLukas } 7923c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 7933c61a47dSLukas } 7943c61a47dSLukas 795d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc, PetscOptionItems *PetscOptionsObject) 796d71ae5a4SJacob Faibussowitsch { 797db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 7988bf83915SBarry Smith PetscBool flag, eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE; 799db966c6cSHong Zhang 800db966c6cSHong Zhang PetscFunctionBegin; 801d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Euclid Options"); 8029566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_euclid_level", "Factorization levels", "None", jac->eu_level, &jac->eu_level, &flag)); 803792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_EuclidSetLevel, jac->hsolver, jac->eu_level); 8048bf83915SBarry Smith 8059566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_euclid_droptolerance", "Drop tolerance for ILU(k) in Euclid", "None", jac->eu_droptolerance, &jac->eu_droptolerance, &flag)); 8068bf83915SBarry Smith if (flag) { 8078bf83915SBarry Smith PetscMPIInt size; 8088bf83915SBarry Smith 8099566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc), &size)); 8107827d75bSBarry Smith PetscCheck(size == 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "hypre's Euclid does not support a parallel drop tolerance"); 811792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetILUT, jac->hsolver, jac->eu_droptolerance); 8128bf83915SBarry Smith } 8138bf83915SBarry Smith 8149566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj, &eu_bj, &flag)); 8158bf83915SBarry Smith if (flag) { 8168bf83915SBarry Smith jac->eu_bj = eu_bj ? 1 : 0; 817792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetBJ, jac->hsolver, jac->eu_bj); 8188bf83915SBarry Smith } 819d0609cedSBarry Smith PetscOptionsHeadEnd(); 8203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 821db966c6cSHong Zhang } 822db966c6cSHong Zhang 823d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Euclid(PC pc, PetscViewer viewer) 824d71ae5a4SJacob Faibussowitsch { 825db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 826db966c6cSHong Zhang PetscBool iascii; 827db966c6cSHong Zhang 828db966c6cSHong Zhang PetscFunctionBegin; 8299566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 830db966c6cSHong Zhang if (iascii) { 8319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Euclid preconditioning\n")); 832db966c6cSHong Zhang if (jac->eu_level != PETSC_DEFAULT) { 83363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factorization levels %" PetscInt_FMT "\n", jac->eu_level)); 834db966c6cSHong Zhang } else { 8359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factorization levels \n")); 836db966c6cSHong Zhang } 8379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->eu_droptolerance)); 83863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 839db966c6cSHong Zhang } 8403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 841db966c6cSHong Zhang } 842db966c6cSHong Zhang 843d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc, Vec b, Vec x) 844d71ae5a4SJacob Faibussowitsch { 84516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 846f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 84716d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 84816d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 84916d9e3a6SLisandro Dalcin 85016d9e3a6SLisandro Dalcin PetscFunctionBegin; 8519566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 8529566063dSJacob Faibussowitsch PetscCall(VecSet(x, 0.0)); 8539566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->x, b)); 8549566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->b, x)); 85516d9e3a6SLisandro Dalcin 856792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 857792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 858792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 85916d9e3a6SLisandro Dalcin 8609371c9d4SSatish Balay PetscStackCallExternalVoid( 8619371c9d4SSatish Balay "Hypre Transpose solve", do { 8625f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver, hmat, jbv, jxv); 8635f80ce2aSJacob Faibussowitsch if (hierr) { 86416d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 8655f80ce2aSJacob Faibussowitsch PetscCheck(hierr == 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 86685245615SPierre Jolivet HYPRE_ClearAllErrors(); 8675f80ce2aSJacob Faibussowitsch } 8685f80ce2aSJacob Faibussowitsch } while (0)); 86916d9e3a6SLisandro Dalcin 8709566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 8719566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 8723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 87316d9e3a6SLisandro Dalcin } 87416d9e3a6SLisandro Dalcin 875d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char name[]) 876d71ae5a4SJacob Faibussowitsch { 877db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 878db6f9c32SMark Adams PetscBool flag; 879db6f9c32SMark Adams 880db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 881db6f9c32SMark Adams PetscFunctionBegin; 882db6f9c32SMark Adams if (jac->spgemm_type) { 8839566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->spgemm_type, name, &flag)); 88428b400f6SJacob Faibussowitsch PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "Cannot reset the HYPRE SpGEMM (really we can)"); 8853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 886db6f9c32SMark Adams } else { 8879566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->spgemm_type)); 888db6f9c32SMark Adams } 8899566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("cusparse", jac->spgemm_type, &flag)); 890db6f9c32SMark Adams if (flag) { 891792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 1); 8923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 893db6f9c32SMark Adams } 8949566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("hypre", jac->spgemm_type, &flag)); 895db6f9c32SMark Adams if (flag) { 896792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 0); 8973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 898db6f9c32SMark Adams } 899db6f9c32SMark Adams jac->spgemm_type = NULL; 9002d6c3ceeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE SpGEMM type %s; Choices are cusparse, hypre", name); 901db6f9c32SMark Adams #endif 902db6f9c32SMark Adams } 903db6f9c32SMark Adams 904d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[]) 905d71ae5a4SJacob Faibussowitsch { 906db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 907db6f9c32SMark Adams 908db6f9c32SMark Adams PetscFunctionBegin; 909db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 910db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 911db6f9c32SMark Adams *spgemm = jac->spgemm_type; 912db6f9c32SMark Adams #endif 9133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 914db6f9c32SMark Adams } 915db6f9c32SMark Adams 91616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"", "V", "W"}; 9170f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP", "Ruge-Stueben", "", "modifiedRuge-Stueben", "", "", "Falgout", "", "PMIS", "", "HMIS"}; 91816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local", "global"}; 91965de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 9203c61a47dSLukas static const char *HYPREBoomerAMGSmoothType[] = {"ILU", "Schwarz-smoothers", "Pilut", "ParaSails", "Euclid"}; 9219371c9d4SSatish 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"}; 9229371c9d4SSatish 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"}; 923d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc, PetscOptionItems *PetscOptionsObject) 924d71ae5a4SJacob Faibussowitsch { 92516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 92622e51d31SStefano Zampini PetscInt bs, n, indx, level; 927ace3abfcSBarry Smith PetscBool flg, tmp_truth; 92873dcfd97SStefano Zampini PetscReal tmpdbl, twodbl[2]; 929589dcaf0SStefano Zampini const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 930db6f9c32SMark Adams const char *PCHYPRESpgemmTypes[] = {"cusparse", "hypre"}; 93116d9e3a6SLisandro Dalcin 93216d9e3a6SLisandro Dalcin PetscFunctionBegin; 933d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE BoomerAMG Options"); 9349566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type", "Cycle type", "None", HYPREBoomerAMGCycleType + 1, 2, HYPREBoomerAMGCycleType[jac->cycletype], &indx, &flg)); 93516d9e3a6SLisandro Dalcin if (flg) { 9364336a9eeSBarry Smith jac->cycletype = indx + 1; 937792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 93816d9e3a6SLisandro Dalcin } 93952ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_levels", "Number of levels (of grids) allowed", "None", jac->maxlevels, &jac->maxlevels, &flg, 2)); 94052ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 94152ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_iter", "Maximum iterations used PER hypre call", "None", jac->maxiter, &jac->maxiter, &flg, 1)); 94252ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 94352ce0ab5SPierre 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)); 94452ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 94522e51d31SStefano Zampini bs = 1; 94648a46eb9SPierre Jolivet if (pc->pmat) PetscCall(MatGetBlockSize(pc->pmat, &bs)); 9479566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions", "Number of functions", "HYPRE_BoomerAMGSetNumFunctions", bs, &bs, &flg)); 94848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 94916d9e3a6SLisandro Dalcin 95052ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_truncfactor", "Truncation factor for interpolation (0=no truncation)", "None", jac->truncfactor, &jac->truncfactor, &flg, 0.0)); 95152ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 95216d9e3a6SLisandro Dalcin 95352ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_P_max", "Max elements per row for interpolation operator (0=unlimited)", "None", jac->pmax, &jac->pmax, &flg, 0)); 95452ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 9550f1074feSSatish Balay 9569566063dSJacob 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)); 957792fecdfSBarry Smith if (flg) PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 9580f1074feSSatish Balay 95952ce0ab5SPierre 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)); 96052ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 9610f1074feSSatish Balay 96252ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_strong_threshold", "Threshold for being strongly connected", "None", jac->strongthreshold, &jac->strongthreshold, &flg, 0.0)); 96352ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 96452ce0ab5SPierre Jolivet PetscCall(PetscOptionsRangeReal("-pc_hypre_boomeramg_max_row_sum", "Maximum row sum", "None", jac->maxrowsum, &jac->maxrowsum, &flg, 0.0, 1.0)); 96552ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 96616d9e3a6SLisandro Dalcin 96716d9e3a6SLisandro Dalcin /* Grid sweeps */ 9689566063dSJacob 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)); 96916d9e3a6SLisandro Dalcin if (flg) { 970792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps, jac->hsolver, indx); 97116d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 97216d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 9730f1074feSSatish Balay jac->gridsweeps[1] = indx; 9740f1074feSSatish Balay /*defaults coarse to 1 */ 9750f1074feSSatish Balay jac->gridsweeps[2] = 1; 97616d9e3a6SLisandro Dalcin } 9779566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen", "Use a nodal based coarsening 1-6", "HYPRE_BoomerAMGSetNodal", jac->nodal_coarsening, &jac->nodal_coarsening, &flg)); 97848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodal, jac->hsolver, jac->nodal_coarsening); 9799566063dSJacob 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)); 98048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodalDiag, jac->hsolver, jac->nodal_coarsening_diag); 9819566063dSJacob 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)); 98248a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecVariant, jac->hsolver, jac->vec_interp_variant); 9839566063dSJacob 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)); 98448a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecQMax, jac->hsolver, jac->vec_interp_qmax); 9859566063dSJacob 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)); 98648a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetSmoothInterpVectors, jac->hsolver, jac->vec_interp_smooth); 9879566063dSJacob 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)); 98848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpRefine, jac->hsolver, jac->interp_refine); 9899566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down", "Number of sweeps for the down cycles", "None", jac->gridsweeps[0], &indx, &flg)); 99016d9e3a6SLisandro Dalcin if (flg) { 991792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 1); 9920f1074feSSatish Balay jac->gridsweeps[0] = indx; 99316d9e3a6SLisandro Dalcin } 9949566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up", "Number of sweeps for the up cycles", "None", jac->gridsweeps[1], &indx, &flg)); 99516d9e3a6SLisandro Dalcin if (flg) { 996792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 2); 9970f1074feSSatish Balay jac->gridsweeps[1] = indx; 99816d9e3a6SLisandro Dalcin } 9999566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse", "Number of sweeps for the coarse level", "None", jac->gridsweeps[2], &indx, &flg)); 100016d9e3a6SLisandro Dalcin if (flg) { 1001792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 3); 10020f1074feSSatish Balay jac->gridsweeps[2] = indx; 100316d9e3a6SLisandro Dalcin } 100416d9e3a6SLisandro Dalcin 10056a251517SEike Mueller /* Smooth type */ 1006dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type", "Enable more complex smoothers", "None", HYPREBoomerAMGSmoothType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType), HYPREBoomerAMGSmoothType[0], &indx, &flg)); 10076a251517SEike Mueller if (flg) { 10086a251517SEike Mueller jac->smoothtype = indx; 10093c61a47dSLukas PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, indx + 5); 10108131ecf7SEike Mueller jac->smoothnumlevels = 25; 1011792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, 25); 10128131ecf7SEike Mueller } 10138131ecf7SEike Mueller 10148131ecf7SEike Mueller /* Number of smoothing levels */ 10159566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels", "Number of levels on which more complex smoothers are used", "None", 25, &indx, &flg)); 10168131ecf7SEike Mueller if (flg && (jac->smoothtype != -1)) { 10178131ecf7SEike Mueller jac->smoothnumlevels = indx; 1018792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, indx); 10196a251517SEike Mueller } 10206a251517SEike Mueller 10213c61a47dSLukas /* Smooth num sweeps */ 10223c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_sweeps", "Set number of smoother sweeps", "None", 1, &indx, &flg)); 10233c61a47dSLukas if (flg && indx > 0) { 10243c61a47dSLukas jac->smoothsweeps = indx; 10253c61a47dSLukas PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumSweeps, jac->hsolver, indx); 10263c61a47dSLukas } 10273c61a47dSLukas 10283c61a47dSLukas /* ILU: ILU Type */ 10293c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_ilu_type", "Choose ILU Type", "None", HYPREILUType, PETSC_STATIC_ARRAY_LENGTH(HYPREILUType), HYPREILUType[0], &indx, &flg)); 10303c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUType, jac->hsolver, indx); } 10313c61a47dSLukas 10323c61a47dSLukas /* ILU: ILU iterative setup type*/ 10333c61a47dSLukas 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)); 10343c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupType, jac->hsolver, indx); } 10353c61a47dSLukas 10363c61a47dSLukas /* ILU: ILU iterative setup option*/ 10373c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_iterative_setup_option", "Set ILU iterative setup option", "None", 0, &indx, &flg)); 10383c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupOption, jac->hsolver, indx); } 10393c61a47dSLukas 10403c61a47dSLukas /* ILU: ILU iterative setup maxiter */ 10413c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_iterative_setup_maxiter", "Set ILU iterative setup maximum iteration count", "None", 0, &indx, &flg)); 10423c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupMaxIter, jac->hsolver, indx); } 10433c61a47dSLukas 10443c61a47dSLukas /* ILU: ILU iterative setup tolerance */ 10453c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_ilu_iterative_setup_tolerance", "Set ILU iterative setup tolerance", "None", 0, &tmpdbl, &flg)); 10463c61a47dSLukas if (flg) { PetscCallExternal(hypre_BoomerAMGSetILUIterSetupTolerance, jac->hsolver, tmpdbl); } 10473c61a47dSLukas 10483c61a47dSLukas /* ILU: ILU Print Level */ 10493c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_print_level", "Set ILU print level", "None", 0, &indx, &flg)); 10503c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel, jac->hsolver, indx); } 10513c61a47dSLukas 10523c61a47dSLukas /* ILU: Logging */ 10533c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_logging", "Set ILU logging level", "None", 0, &indx, &flg)); 10543c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetLogging, jac->hsolver, indx); } 10553c61a47dSLukas 10563c61a47dSLukas /* ILU: ILU Level */ 10573c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_level", "Set ILU level", "None", 0, &indx, &flg)); 10583c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILULevel, jac->hsolver, indx); } 10593c61a47dSLukas 10603c61a47dSLukas /* ILU: ILU Max NNZ per row */ 10613c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_max_nnz_per_row", "Set maximum NNZ per row", "None", 0, &indx, &flg)); 10623c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUMaxRowNnz, jac->hsolver, indx); } 10633c61a47dSLukas 10643c61a47dSLukas /* ILU: maximum iteration count */ 10653c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_maxiter", "Set ILU max iterations", "None", 0, &indx, &flg)); 10663c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUMaxIter, jac->hsolver, indx); } 10673c61a47dSLukas 10683c61a47dSLukas /* ILU: drop threshold */ 10693c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_ilu_drop_tol", "Drop tolerance for ILU", "None", 0, &tmpdbl, &flg)); 10703c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUDroptol, jac->hsolver, tmpdbl); } 10713c61a47dSLukas 10723c61a47dSLukas /* ILU: Triangular Solve */ 10733c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_ilu_tri_solve", "Enable triangular solve", "None", PETSC_FALSE, &tmp_truth, &flg)); 10743c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUTriSolve, jac->hsolver, tmp_truth); } 10753c61a47dSLukas 10763c61a47dSLukas /* ILU: Lower Jacobi iteration */ 10773c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_lower_jacobi_iters", "Set lower Jacobi iteration count", "None", 0, &indx, &flg)); 10783c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILULowerJacobiIters, jac->hsolver, indx); } 10793c61a47dSLukas 10803c61a47dSLukas /* ILU: Upper Jacobi iteration */ 10813c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_upper_jacobi_iters", "Set upper Jacobi iteration count", "None", 0, &indx, &flg)); 10823c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUUpperJacobiIters, jac->hsolver, indx); } 10833c61a47dSLukas 10843c61a47dSLukas /* ILU: local reordering */ 10853c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_ilu_local_reordering", "Enable local reordering", "None", PETSC_FALSE, &tmp_truth, &flg)); 10863c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILULocalReordering, jac->hsolver, tmp_truth); } 10873c61a47dSLukas 10881810e44eSEike Mueller /* Number of levels for ILU(k) for Euclid */ 10899566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level", "Number of levels for ILU(k) in Euclid smoother", "None", 0, &indx, &flg)); 10903c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 10911810e44eSEike Mueller jac->eu_level = indx; 1092792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, indx); 10931810e44eSEike Mueller } 10941810e44eSEike Mueller 10951810e44eSEike Mueller /* Filter for ILU(k) for Euclid */ 109673dcfd97SStefano Zampini PetscReal droptolerance; 10979566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance", "Drop tolerance for ILU(k) in Euclid smoother", "None", 0, &droptolerance, &flg)); 10983c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 10991810e44eSEike Mueller jac->eu_droptolerance = droptolerance; 1100792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, droptolerance); 11011810e44eSEike Mueller } 11021810e44eSEike Mueller 11031810e44eSEike Mueller /* Use Block Jacobi ILUT for Euclid */ 11049566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg)); 11053c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 11061810e44eSEike Mueller jac->eu_bj = tmp_truth; 1107792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuBJ, jac->hsolver, jac->eu_bj); 11081810e44eSEike Mueller } 11091810e44eSEike Mueller 111016d9e3a6SLisandro Dalcin /* Relax type */ 1111dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all", "Relax type for the up and down cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[6], &indx, &flg)); 111216d9e3a6SLisandro Dalcin if (flg) { 11130f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 1114792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, indx); 11150f1074feSSatish Balay /* by default, coarse type set to 9 */ 11160f1074feSSatish Balay jac->relaxtype[2] = 9; 1117792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, 9, 3); 111816d9e3a6SLisandro Dalcin } 1119dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down", "Relax type for the down cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[6], &indx, &flg)); 112016d9e3a6SLisandro Dalcin if (flg) { 112116d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 1122792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 1); 112316d9e3a6SLisandro Dalcin } 1124dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up", "Relax type for the up cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[6], &indx, &flg)); 112516d9e3a6SLisandro Dalcin if (flg) { 11260f1074feSSatish Balay jac->relaxtype[1] = indx; 1127792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 2); 112816d9e3a6SLisandro Dalcin } 1129dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse", "Relax type on coarse grid", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[9], &indx, &flg)); 113016d9e3a6SLisandro Dalcin if (flg) { 11310f1074feSSatish Balay jac->relaxtype[2] = indx; 1132792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 3); 113316d9e3a6SLisandro Dalcin } 113416d9e3a6SLisandro Dalcin 113516d9e3a6SLisandro Dalcin /* Relaxation Weight */ 11369566063dSJacob 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)); 113716d9e3a6SLisandro Dalcin if (flg) { 1138792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxWt, jac->hsolver, tmpdbl); 113916d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 114016d9e3a6SLisandro Dalcin } 114116d9e3a6SLisandro Dalcin 114216d9e3a6SLisandro Dalcin n = 2; 114316d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 11449566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level", "Set the relaxation weight for a particular level (weight,level)", "None", twodbl, &n, &flg)); 114516d9e3a6SLisandro Dalcin if (flg) { 11460fdf79fbSJacob 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); 114716d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 1148792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelRelaxWt, jac->hsolver, twodbl[0], indx); 114916d9e3a6SLisandro Dalcin } 115016d9e3a6SLisandro Dalcin 115116d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 11529566063dSJacob 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)); 115316d9e3a6SLisandro Dalcin if (flg) { 1154792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOuterWt, jac->hsolver, tmpdbl); 115516d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 115616d9e3a6SLisandro Dalcin } 115716d9e3a6SLisandro Dalcin 115816d9e3a6SLisandro Dalcin n = 2; 115916d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 11609566063dSJacob 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)); 116116d9e3a6SLisandro Dalcin if (flg) { 11620fdf79fbSJacob 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); 116316d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 1164792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelOuterWt, jac->hsolver, twodbl[0], indx); 116516d9e3a6SLisandro Dalcin } 116616d9e3a6SLisandro Dalcin 116716d9e3a6SLisandro Dalcin /* the Relax Order */ 11689566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg)); 116916d9e3a6SLisandro Dalcin 11708afaa268SBarry Smith if (flg && tmp_truth) { 117116d9e3a6SLisandro Dalcin jac->relaxorder = 0; 1172792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 117316d9e3a6SLisandro Dalcin } 1174dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type", "Measure type", "None", HYPREBoomerAMGMeasureType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType), HYPREBoomerAMGMeasureType[0], &indx, &flg)); 117516d9e3a6SLisandro Dalcin if (flg) { 117616d9e3a6SLisandro Dalcin jac->measuretype = indx; 1177792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 117816d9e3a6SLisandro Dalcin } 11790f1074feSSatish Balay /* update list length 3/07 */ 1180dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type", "Coarsen type", "None", HYPREBoomerAMGCoarsenType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType), HYPREBoomerAMGCoarsenType[6], &indx, &flg)); 118116d9e3a6SLisandro Dalcin if (flg) { 118216d9e3a6SLisandro Dalcin jac->coarsentype = indx; 1183792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 118416d9e3a6SLisandro Dalcin } 11850f1074feSSatish Balay 11869566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg)); 118748a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 11889566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg)); 118948a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 1190db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 1191db6f9c32SMark Adams // global parameter but is closely associated with BoomerAMG 1192dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_mg_galerkin_mat_product_algorithm", "Type of SpGEMM to use in hypre (only for now)", "PCMGGalerkinSetMatProductAlgorithm", PCHYPRESpgemmTypes, PETSC_STATIC_ARRAY_LENGTH(PCHYPRESpgemmTypes), PCHYPRESpgemmTypes[0], &indx, &flg)); 11932d6c3ceeSStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1194db6f9c32SMark Adams if (!flg) indx = 0; 11959566063dSJacob Faibussowitsch PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, PCHYPRESpgemmTypes[indx])); 11962d6c3ceeSStefano Zampini #else 11972d6c3ceeSStefano Zampini PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, "hypre")); 11982d6c3ceeSStefano Zampini #endif 1199db6f9c32SMark Adams #endif 1200589dcaf0SStefano Zampini /* AIR */ 1201589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 12029566063dSJacob 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)); 1203792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 1204589dcaf0SStefano Zampini if (jac->Rtype) { 120519be502cSAlexander HYPRE_Int **grid_relax_points = hypre_TAlloc(HYPRE_Int *, 4, HYPRE_MEMORY_HOST); 120619be502cSAlexander char *prerelax[256]; 120719be502cSAlexander char *postrelax[256]; 120819be502cSAlexander char stringF[2] = "F", stringC[2] = "C", stringA[2] = "A"; 120919be502cSAlexander PetscInt ns_down = 256, ns_up = 256; 121019be502cSAlexander PetscBool matchF, matchC, matchA; 121119be502cSAlexander 1212589dcaf0SStefano 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 */ 1213589dcaf0SStefano Zampini 12149566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR", "Threshold for R", "None", jac->Rstrongthreshold, &jac->Rstrongthreshold, NULL)); 1215792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 1216589dcaf0SStefano Zampini 12179566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR", "Filter threshold for R", "None", jac->Rfilterthreshold, &jac->Rfilterthreshold, NULL)); 1218792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 1219589dcaf0SStefano Zampini 12209566063dSJacob 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)); 1221792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 1222589dcaf0SStefano Zampini 12239566063dSJacob 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)); 1224792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 122519be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_prerelax", "Defines prerelax scheme", "None", prerelax, &ns_down, NULL)); 122619be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_postrelax", "Defines postrelax scheme", "None", postrelax, &ns_up, NULL)); 122719be502cSAlexander 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"); 122819be502cSAlexander 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"); 122919be502cSAlexander 123019be502cSAlexander grid_relax_points[0] = NULL; 123119be502cSAlexander grid_relax_points[1] = hypre_TAlloc(HYPRE_Int, ns_down, HYPRE_MEMORY_HOST); 123219be502cSAlexander grid_relax_points[2] = hypre_TAlloc(HYPRE_Int, ns_up, HYPRE_MEMORY_HOST); 123319be502cSAlexander grid_relax_points[3] = hypre_TAlloc(HYPRE_Int, jac->gridsweeps[2], HYPRE_MEMORY_HOST); 123419be502cSAlexander grid_relax_points[3][0] = 0; 123519be502cSAlexander 123619be502cSAlexander // set down relax scheme 123719be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) { 123819be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringF, &matchF)); 123919be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringC, &matchC)); 124019be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringA, &matchA)); 124119be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_prerelax are C, F, and A"); 124219be502cSAlexander if (matchF) grid_relax_points[1][i] = -1; 124319be502cSAlexander else if (matchC) grid_relax_points[1][i] = 1; 124419be502cSAlexander else if (matchA) grid_relax_points[1][i] = 0; 124519be502cSAlexander } 124619be502cSAlexander 124719be502cSAlexander // set up relax scheme 124819be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) { 124919be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringF, &matchF)); 125019be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringC, &matchC)); 125119be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringA, &matchA)); 125219be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_postrelax are C, F, and A"); 125319be502cSAlexander if (matchF) grid_relax_points[2][i] = -1; 125419be502cSAlexander else if (matchC) grid_relax_points[2][i] = 1; 125519be502cSAlexander else if (matchA) grid_relax_points[2][i] = 0; 125619be502cSAlexander } 125719be502cSAlexander 125819be502cSAlexander // set coarse relax scheme 125919be502cSAlexander for (PetscInt i = 0; i < jac->gridsweeps[2]; i++) grid_relax_points[3][i] = 0; 126019be502cSAlexander 126119be502cSAlexander // Pass relax schemes to hypre 126219be502cSAlexander PetscCallExternal(HYPRE_BoomerAMGSetGridRelaxPoints, jac->hsolver, grid_relax_points); 126319be502cSAlexander 126419be502cSAlexander // cleanup memory 126519be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) PetscCall(PetscFree(prerelax[i])); 126619be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) PetscCall(PetscFree(postrelax[i])); 1267589dcaf0SStefano Zampini } 1268589dcaf0SStefano Zampini #endif 1269589dcaf0SStefano Zampini 1270ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9, 9, 9) 127163a3b9bcSJacob 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); 1272ecae95adSPierre Jolivet #endif 1273ecae95adSPierre Jolivet 12740f1074feSSatish Balay /* new 3/07 */ 1275dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type", "Interpolation type", "None", HYPREBoomerAMGInterpType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType), HYPREBoomerAMGInterpType[0], &indx, &flg)); 1276589dcaf0SStefano Zampini if (flg || jac->Rtype) { 1277589dcaf0SStefano Zampini if (flg) jac->interptype = indx; 1278792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 12790f1074feSSatish Balay } 12800f1074feSSatish Balay 12819566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", &flg)); 128216d9e3a6SLisandro Dalcin if (flg) { 1283b96a4a96SBarry Smith level = 3; 12849566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", level, &level, NULL)); 12852fa5cd67SKarl Rupp 1286b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1287792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel, jac->hsolver, level); 12882ae77aedSBarry Smith } 12892ae77aedSBarry Smith 12909566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", &flg)); 12912ae77aedSBarry Smith if (flg) { 1292b96a4a96SBarry Smith level = 3; 12939566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", level, &level, NULL)); 12942fa5cd67SKarl Rupp 1295b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1296792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDebugFlag, jac->hsolver, level); 129716d9e3a6SLisandro Dalcin } 12988f87f92bSBarry Smith 12999566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg)); 13008f87f92bSBarry Smith if (flg && tmp_truth) { 13018f87f92bSBarry Smith PetscInt tmp_int; 13029566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", jac->nodal_relax_levels, &tmp_int, &flg)); 13038f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 1304792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, 6); 1305792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDomainType, jac->hsolver, 1); 1306792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOverlap, jac->hsolver, 0); 1307792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, jac->nodal_relax_levels); 13088f87f92bSBarry Smith } 13098f87f92bSBarry Smith 13109566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL)); 1311792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 1312589dcaf0SStefano Zampini 1313589dcaf0SStefano Zampini /* options for ParaSails solvers */ 1314dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flg)); 1315589dcaf0SStefano Zampini if (flg) { 1316589dcaf0SStefano Zampini jac->symt = indx; 1317792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSym, jac->hsolver, jac->symt); 1318589dcaf0SStefano Zampini } 1319589dcaf0SStefano Zampini 1320d0609cedSBarry Smith PetscOptionsHeadEnd(); 13213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 132216d9e3a6SLisandro Dalcin } 132316d9e3a6SLisandro Dalcin 1324d71ae5a4SJacob 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) 1325d71ae5a4SJacob Faibussowitsch { 132616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 13272cf14000SStefano Zampini HYPRE_Int oits; 132816d9e3a6SLisandro Dalcin 132916d9e3a6SLisandro Dalcin PetscFunctionBegin; 13309566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 1331792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, its * jac->maxiter); 1332792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, rtol); 133316d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 13349566063dSJacob Faibussowitsch PetscCall(PCApply_HYPRE(pc, b, y)); 133516d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 1336792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGGetNumIterations, jac->hsolver, &oits); 13374d0a8057SBarry Smith *outits = oits; 13384d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 13394d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1340792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 1341792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 13423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 134316d9e3a6SLisandro Dalcin } 134416d9e3a6SLisandro Dalcin 1345d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc, PetscViewer viewer) 1346d71ae5a4SJacob Faibussowitsch { 134716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 13483c61a47dSLukas hypre_ParAMGData *amg_data = (hypre_ParAMGData *)jac->hsolver; 1349ace3abfcSBarry Smith PetscBool iascii; 13503c61a47dSLukas PetscInt indx; 13513c61a47dSLukas PetscReal val; 135216d9e3a6SLisandro Dalcin 135316d9e3a6SLisandro Dalcin PetscFunctionBegin; 13549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 135516d9e3a6SLisandro Dalcin if (iascii) { 13569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE BoomerAMG preconditioning\n")); 13579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Cycle type %s\n", HYPREBoomerAMGCycleType[jac->cycletype])); 135863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of levels %" PetscInt_FMT "\n", jac->maxlevels)); 135963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of iterations PER hypre call %" PetscInt_FMT "\n", jac->maxiter)); 13609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Convergence tolerance PER hypre call %g\n", (double)jac->tol)); 13619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for strong coupling %g\n", (double)jac->strongthreshold)); 13629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation truncation factor %g\n", (double)jac->truncfactor)); 136363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: max elements per row %" PetscInt_FMT "\n", jac->pmax)); 136448a46eb9SPierre Jolivet if (jac->interp_refine) PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n", jac->interp_refine)); 136563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of levels of aggressive coarsening %" PetscInt_FMT "\n", jac->agg_nl)); 136663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of paths for aggressive coarsening %" PetscInt_FMT "\n", jac->agg_num_paths)); 13670f1074feSSatish Balay 13689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum row sums %g\n", (double)jac->maxrowsum)); 136916d9e3a6SLisandro Dalcin 137063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps down %" PetscInt_FMT "\n", jac->gridsweeps[0])); 137163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps up %" PetscInt_FMT "\n", jac->gridsweeps[1])); 137263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps on coarse %" PetscInt_FMT "\n", jac->gridsweeps[2])); 137316d9e3a6SLisandro Dalcin 13749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax down %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[0]])); 13759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax up %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[1]])); 13769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax on coarse %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[2]])); 137716d9e3a6SLisandro Dalcin 13789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax weight (all) %g\n", (double)jac->relaxweight)); 13799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Outer relax weight (all) %g\n", (double)jac->outerrelaxweight)); 138016d9e3a6SLisandro Dalcin 138119be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum size of coarsest grid %" PetscInt_FMT "\n", jac->maxc)); 138219be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Minimum size of coarsest grid %" PetscInt_FMT "\n", jac->minc)); 138319be502cSAlexander 138416d9e3a6SLisandro Dalcin if (jac->relaxorder) { 13859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using CF-relaxation\n")); 138616d9e3a6SLisandro Dalcin } else { 13879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using CF-relaxation\n")); 138816d9e3a6SLisandro Dalcin } 13896a251517SEike Mueller if (jac->smoothtype != -1) { 13909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth type %s\n", HYPREBoomerAMGSmoothType[jac->smoothtype])); 139163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num levels %" PetscInt_FMT "\n", jac->smoothnumlevels)); 13923c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num sweeps %" PetscInt_FMT "\n", jac->smoothsweeps)); 13933c61a47dSLukas if (jac->smoothtype == 0) { 13943c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUType", indx = hypre_ParAMGDataILUType(amg_data)); 13953c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU type %s (%" PetscInt_FMT ")\n", HYPREILUType[indx], indx)); 13963c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULevel", indx = hypre_ParAMGDataILULevel(amg_data)); 13973c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU level %" PetscInt_FMT "\n", indx)); 13983c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUMaxIter", indx = hypre_ParAMGDataILUMaxIter(amg_data)); 13993c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max iterations %" PetscInt_FMT "\n", indx)); 14003c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUMaxRowNnz", indx = hypre_ParAMGDataILUMaxRowNnz(amg_data)); 14013c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max NNZ per row %" PetscInt_FMT "\n", indx)); 14023c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUTriSolve", indx = hypre_ParAMGDataILUTriSolve(amg_data)); 14033c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU triangular solve %" PetscInt_FMT "\n", indx)); 14043c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataTol", val = hypre_ParAMGDataTol(amg_data)); 14053c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU tolerance %e\n", val)); 14063c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUDroptol", val = hypre_ParAMGDataILUDroptol(amg_data)); 14073c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU drop tolerance %e\n", val)); 14083c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULocalReordering", indx = hypre_ParAMGDataILULocalReordering(amg_data)); 14093c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU local reordering %" PetscInt_FMT "\n", indx)); 14103c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULowerJacobiIters", indx = hypre_ParAMGDataILULowerJacobiIters(amg_data)); 14113c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU lower Jacobi iterations %" PetscInt_FMT "\n", indx)); 14123c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUUpperJacobiIters", indx = hypre_ParAMGDataILUUpperJacobiIters(amg_data)); 14133c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU upper Jacobi iterations %" PetscInt_FMT "\n", indx)); 14143c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataPrintLevel", indx = hypre_ParAMGDataPrintLevel(amg_data)); 14153c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU print level %" PetscInt_FMT "\n", indx)); 14163c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataLogging", indx = hypre_ParAMGDataLogging(amg_data)); 14173c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU logging level %" PetscInt_FMT "\n", indx)); 14183c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupType", indx = hypre_ParAMGDataILUIterSetupType(amg_data)); 14193c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup type %s (%" PetscInt_FMT ")\n", HYPREILUIterSetup[indx], indx)); 14203c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupOption", indx = hypre_ParAMGDataILUIterSetupOption(amg_data)); 14213c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup option %" PetscInt_FMT "\n", indx)); 14223c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupMaxIter", indx = hypre_ParAMGDataILUIterSetupMaxIter(amg_data)); 14233c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup max iterations %" PetscInt_FMT "\n", indx)); 14243c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupTolerance", val = hypre_ParAMGDataILUIterSetupTolerance(amg_data)); 14253c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup tolerance %e\n", val)); 14263c61a47dSLukas } 14277e352d70SEike Mueller } else { 14289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using more complex smoothers.\n")); 14291810e44eSEike Mueller } 14301810e44eSEike Mueller if (jac->smoothtype == 3) { 143163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) levels %" PetscInt_FMT "\n", jac->eu_level)); 14329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) drop tolerance %g\n", (double)jac->eu_droptolerance)); 143363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 14346a251517SEike Mueller } 14359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Measure type %s\n", HYPREBoomerAMGMeasureType[jac->measuretype])); 14369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Coarsen type %s\n", HYPREBoomerAMGCoarsenType[jac->coarsentype])); 14379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation type %s\n", jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt")); 143848a46eb9SPierre Jolivet if (jac->nodal_coarsening) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n", jac->nodal_coarsening)); 14395272c319SBarry Smith if (jac->vec_interp_variant) { 144063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n", jac->vec_interp_variant)); 144163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n", jac->vec_interp_qmax)); 14429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n", jac->vec_interp_smooth)); 14438f87f92bSBarry Smith } 144448a46eb9SPierre Jolivet if (jac->nodal_relax) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n", jac->nodal_relax_levels)); 1445db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 14469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", jac->spgemm_type)); 14472d6c3ceeSStefano Zampini #else 14482d6c3ceeSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", "hypre")); 1449db6f9c32SMark Adams #endif 1450589dcaf0SStefano Zampini /* AIR */ 1451589dcaf0SStefano Zampini if (jac->Rtype) { 145263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using approximate ideal restriction type %" PetscInt_FMT "\n", jac->Rtype)); 14539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for R %g\n", (double)jac->Rstrongthreshold)); 14549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Filter for R %g\n", (double)jac->Rfilterthreshold)); 14559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop tolerance %g\n", (double)jac->Adroptol)); 145663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop type %" PetscInt_FMT "\n", jac->Adroptype)); 1457589dcaf0SStefano Zampini } 145816d9e3a6SLisandro Dalcin } 14593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 146016d9e3a6SLisandro Dalcin } 146116d9e3a6SLisandro Dalcin 1462d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc, PetscOptionItems *PetscOptionsObject) 1463d71ae5a4SJacob Faibussowitsch { 146416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 14654ddd07fcSJed Brown PetscInt indx; 1466ace3abfcSBarry Smith PetscBool flag; 146716d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 146816d9e3a6SLisandro Dalcin 146916d9e3a6SLisandro Dalcin PetscFunctionBegin; 1470d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ParaSails Options"); 14719566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels", "Number of number of levels", "None", jac->nlevels, &jac->nlevels, 0)); 14729566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh", "Threshold", "None", jac->threshold, &jac->threshold, &flag)); 1473792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 147416d9e3a6SLisandro Dalcin 14759566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter", "filter", "None", jac->filter, &jac->filter, &flag)); 1476792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 147716d9e3a6SLisandro Dalcin 14789566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal", "Load balance", "None", jac->loadbal, &jac->loadbal, &flag)); 1479792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 148016d9e3a6SLisandro Dalcin 14819566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging", "Print info to screen", "None", (PetscBool)jac->logging, (PetscBool *)&jac->logging, &flag)); 1482792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 148316d9e3a6SLisandro Dalcin 14849566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse", "Reuse nonzero pattern in preconditioner", "None", (PetscBool)jac->ruse, (PetscBool *)&jac->ruse, &flag)); 1485792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 148616d9e3a6SLisandro Dalcin 1487dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flag)); 148816d9e3a6SLisandro Dalcin if (flag) { 148916d9e3a6SLisandro Dalcin jac->symt = indx; 1490792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 149116d9e3a6SLisandro Dalcin } 149216d9e3a6SLisandro Dalcin 1493d0609cedSBarry Smith PetscOptionsHeadEnd(); 14943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 149516d9e3a6SLisandro Dalcin } 149616d9e3a6SLisandro Dalcin 1497d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ParaSails(PC pc, PetscViewer viewer) 1498d71ae5a4SJacob Faibussowitsch { 149916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1500ace3abfcSBarry Smith PetscBool iascii; 1501feb237baSPierre Jolivet const char *symt = 0; 150216d9e3a6SLisandro Dalcin 150316d9e3a6SLisandro Dalcin PetscFunctionBegin; 15049566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 150516d9e3a6SLisandro Dalcin if (iascii) { 15069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ParaSails preconditioning\n")); 150763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " nlevels %" PetscInt_FMT "\n", jac->nlevels)); 15089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " threshold %g\n", (double)jac->threshold)); 15099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " filter %g\n", (double)jac->filter)); 15109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " load balance %g\n", (double)jac->loadbal)); 15119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " reuse nonzero structure %s\n", PetscBools[jac->ruse])); 15129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " print info to screen %s\n", PetscBools[jac->logging])); 15132fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 15142fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 15152fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 151663a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONG, "Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT, jac->symt); 15179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", symt)); 151816d9e3a6SLisandro Dalcin } 15193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 152016d9e3a6SLisandro Dalcin } 1521f1580f4eSBarry Smith 1522d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc, PetscOptionItems *PetscOptionsObject) 1523d71ae5a4SJacob Faibussowitsch { 15244cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 15254cb006feSStefano Zampini PetscInt n; 15264cb006feSStefano Zampini PetscBool flag, flag2, flag3, flag4; 15274cb006feSStefano Zampini 15284cb006feSStefano Zampini PetscFunctionBegin; 1529d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE AMS Options"); 15309566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level", "Debugging output level for AMS", "None", jac->as_print, &jac->as_print, &flag)); 1531792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 15329566063dSJacob 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)); 1533792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 15349566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type", "Cycle type for AMS multigrid", "None", jac->ams_cycle_type, &jac->ams_cycle_type, &flag)); 1535792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 15369566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_tol", "Error tolerance for AMS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1537792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 15389566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type", "Relaxation type for AMS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 15399566063dSJacob 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)); 15409566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight", "Relaxation weight for AMS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 15419566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_omega", "SSOR coefficient for AMS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 154248a46eb9SPierre Jolivet if (flag || flag2 || flag3 || flag4) PetscCallExternal(HYPRE_AMSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 15439566063dSJacob 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)); 15444cb006feSStefano Zampini n = 5; 15459566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options", "AMG options for vector Poisson", "None", jac->as_amg_alpha_opts, &n, &flag2)); 15464cb006feSStefano Zampini if (flag || flag2) { 1547792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1548863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1549863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 15509371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1551a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 15524cb006feSStefano Zampini } 15539566063dSJacob 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)); 15544cb006feSStefano Zampini n = 5; 15559566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options", "AMG options for scalar Poisson solver", "None", jac->as_amg_beta_opts, &n, &flag2)); 15564cb006feSStefano Zampini if (flag || flag2) { 1557792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1558863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1559863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 15609371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1561a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 15624cb006feSStefano Zampini } 15639566063dSJacob 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)); 156423df4f25SStefano Zampini if (flag) { /* override HYPRE's default only if the options is used */ 1565792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetProjectionFrequency, jac->hsolver, jac->ams_proj_freq); 156623df4f25SStefano Zampini } 1567d0609cedSBarry Smith PetscOptionsHeadEnd(); 15683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15694cb006feSStefano Zampini } 15704cb006feSStefano Zampini 1571d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_AMS(PC pc, PetscViewer viewer) 1572d71ae5a4SJacob Faibussowitsch { 15734cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 15744cb006feSStefano Zampini PetscBool iascii; 15754cb006feSStefano Zampini 15764cb006feSStefano Zampini PetscFunctionBegin; 15779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 15784cb006feSStefano Zampini if (iascii) { 15799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE AMS preconditioning\n")); 158063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 158163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 158263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 158363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 158463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 158563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 158663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 15874cb006feSStefano Zampini if (jac->alpha_Poisson) { 15889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (passed in by user)\n")); 15894cb006feSStefano Zampini } else { 15909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (computed) \n")); 15914cb006feSStefano Zampini } 159263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 159363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 159463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 159563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 159663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 159763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 15984cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 15994cb006feSStefano Zampini if (jac->beta_Poisson) { 16009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (passed in by user)\n")); 16014cb006feSStefano Zampini } else { 16029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (computed) \n")); 16034cb006feSStefano Zampini } 160463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 160563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 160663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 160763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 160863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 160963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_beta_theta)); 161048a46eb9SPierre 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)); 161123df4f25SStefano Zampini } else { 16129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver not used (zero-conductivity everywhere) \n")); 16134cb006feSStefano Zampini } 16144cb006feSStefano Zampini } 16153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16164cb006feSStefano Zampini } 16174cb006feSStefano Zampini 1618d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PC pc, PetscOptionItems *PetscOptionsObject) 1619d71ae5a4SJacob Faibussowitsch { 1620863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1621863406b8SStefano Zampini PetscInt n; 1622863406b8SStefano Zampini PetscBool flag, flag2, flag3, flag4; 1623863406b8SStefano Zampini 1624863406b8SStefano Zampini PetscFunctionBegin; 1625d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ADS Options"); 16269566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level", "Debugging output level for ADS", "None", jac->as_print, &jac->as_print, &flag)); 1627792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 16289566063dSJacob 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)); 1629792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 16309566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type", "Cycle type for ADS multigrid", "None", jac->ads_cycle_type, &jac->ads_cycle_type, &flag)); 1631792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ads_cycle_type); 16329566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_tol", "Error tolerance for ADS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1633792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 16349566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type", "Relaxation type for ADS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 16359566063dSJacob 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)); 16369566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight", "Relaxation weight for ADS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 16379566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_omega", "SSOR coefficient for ADS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 163848a46eb9SPierre Jolivet if (flag || flag2 || flag3 || flag4) PetscCallExternal(HYPRE_ADSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 16399566063dSJacob 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)); 1640863406b8SStefano Zampini n = 5; 16419566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options", "AMG options for AMS solver inside ADS", "None", jac->as_amg_alpha_opts, &n, &flag2)); 16429566063dSJacob 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)); 1643863406b8SStefano Zampini if (flag || flag2 || flag3) { 1644792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMS cycle type */ 1645863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1646863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1647863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 16489371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1649a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 1650863406b8SStefano Zampini } 16519566063dSJacob 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)); 1652863406b8SStefano Zampini n = 5; 16539566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options", "AMG options for vector AMG solver inside ADS", "None", jac->as_amg_beta_opts, &n, &flag2)); 1654863406b8SStefano Zampini if (flag || flag2) { 1655792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1656863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1657863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 16589371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1659a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 1660863406b8SStefano Zampini } 1661d0609cedSBarry Smith PetscOptionsHeadEnd(); 16623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1663863406b8SStefano Zampini } 1664863406b8SStefano Zampini 1665d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ADS(PC pc, PetscViewer viewer) 1666d71ae5a4SJacob Faibussowitsch { 1667863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1668863406b8SStefano Zampini PetscBool iascii; 1669863406b8SStefano Zampini 1670863406b8SStefano Zampini PetscFunctionBegin; 16719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1672863406b8SStefano Zampini if (iascii) { 16739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ADS preconditioning\n")); 167463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 167563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ads_cycle_type)); 167663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 167763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 167863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 167963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 168063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 16819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " AMS solver using boomerAMG\n")); 168263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 168363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 168463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 168563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 168663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 168763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 168863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 16899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver using boomerAMG\n")); 169063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 169163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 169263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 169363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 169463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 169563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_beta_theta)); 1696863406b8SStefano Zampini } 16973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1698863406b8SStefano Zampini } 1699863406b8SStefano Zampini 1700d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G) 1701d71ae5a4SJacob Faibussowitsch { 17024cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 17035ac14e1cSStefano Zampini PetscBool ishypre; 17044cb006feSStefano Zampini 17054cb006feSStefano Zampini PetscFunctionBegin; 17069566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)G, MATHYPRE, &ishypre)); 17075ac14e1cSStefano Zampini if (ishypre) { 17089566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)G)); 17099566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 17105ac14e1cSStefano Zampini jac->G = G; 17115ac14e1cSStefano Zampini } else { 17129566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 17139566063dSJacob Faibussowitsch PetscCall(MatConvert(G, MATHYPRE, MAT_INITIAL_MATRIX, &jac->G)); 17145ac14e1cSStefano Zampini } 17153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17164cb006feSStefano Zampini } 17174cb006feSStefano Zampini 17184cb006feSStefano Zampini /*@ 1719f1580f4eSBarry Smith PCHYPRESetDiscreteGradient - Set discrete gradient matrix for `PCHYPRE` type of ams or ads 17204cb006feSStefano Zampini 1721c3339decSBarry Smith Collective 17224cb006feSStefano Zampini 17234cb006feSStefano Zampini Input Parameters: 17244cb006feSStefano Zampini + pc - the preconditioning context 17254cb006feSStefano Zampini - G - the discrete gradient 17264cb006feSStefano Zampini 17274cb006feSStefano Zampini Level: intermediate 17284cb006feSStefano Zampini 172995452b02SPatrick Sanan Notes: 173095452b02SPatrick Sanan G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 1731147403d9SBarry Smith 1732863406b8SStefano Zampini Each row of G has 2 nonzeros, with column indexes being the global indexes of edge's endpoints: matrix entries are +1 and -1 depending on edge orientation 17334cb006feSStefano Zampini 1734feefa0e1SJacob Faibussowitsch Developer Notes: 1735f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1736f1580f4eSBarry Smith 1737562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteCurl()` 17384cb006feSStefano Zampini @*/ 1739d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 1740d71ae5a4SJacob Faibussowitsch { 17414cb006feSStefano Zampini PetscFunctionBegin; 17424cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 17434cb006feSStefano Zampini PetscValidHeaderSpecific(G, MAT_CLASSID, 2); 17444cb006feSStefano Zampini PetscCheckSameComm(pc, 1, G, 2); 1745cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteGradient_C", (PC, Mat), (pc, G)); 17463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17474cb006feSStefano Zampini } 17484cb006feSStefano Zampini 1749d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C) 1750d71ae5a4SJacob Faibussowitsch { 1751863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 17525ac14e1cSStefano Zampini PetscBool ishypre; 1753863406b8SStefano Zampini 1754863406b8SStefano Zampini PetscFunctionBegin; 17559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C, MATHYPRE, &ishypre)); 17565ac14e1cSStefano Zampini if (ishypre) { 17579566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)C)); 17589566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 17595ac14e1cSStefano Zampini jac->C = C; 17605ac14e1cSStefano Zampini } else { 17619566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 17629566063dSJacob Faibussowitsch PetscCall(MatConvert(C, MATHYPRE, MAT_INITIAL_MATRIX, &jac->C)); 17635ac14e1cSStefano Zampini } 17643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1765863406b8SStefano Zampini } 1766863406b8SStefano Zampini 1767863406b8SStefano Zampini /*@ 17686e415bd2SNuno Nobre PCHYPRESetDiscreteCurl - Set discrete curl matrix for `PCHYPRE` type of ads 1769863406b8SStefano Zampini 1770c3339decSBarry Smith Collective 1771863406b8SStefano Zampini 1772863406b8SStefano Zampini Input Parameters: 1773863406b8SStefano Zampini + pc - the preconditioning context 1774863406b8SStefano Zampini - C - the discrete curl 1775863406b8SStefano Zampini 1776863406b8SStefano Zampini Level: intermediate 1777863406b8SStefano Zampini 177895452b02SPatrick Sanan Notes: 177995452b02SPatrick Sanan C should have as many rows as the number of faces and as many columns as the number of edges in the mesh 1780147403d9SBarry Smith 17816e415bd2SNuno Nobre Each row of C has as many nonzeros as the number of edges of a face, with column indexes being the global indexes of the corresponding edge: matrix entries are +1 and -1 depending on edge orientation with respect to the face orientation 1782863406b8SStefano Zampini 1783feefa0e1SJacob Faibussowitsch Developer Notes: 1784f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1785f1580f4eSBarry Smith 1786f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ads it should be called `PCHYPREADSSetDiscreteCurl()` 1787f1580f4eSBarry Smith 1788562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()` 1789863406b8SStefano Zampini @*/ 1790d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C) 1791d71ae5a4SJacob Faibussowitsch { 1792863406b8SStefano Zampini PetscFunctionBegin; 1793863406b8SStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1794863406b8SStefano Zampini PetscValidHeaderSpecific(C, MAT_CLASSID, 2); 1795863406b8SStefano Zampini PetscCheckSameComm(pc, 1, C, 2); 1796cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteCurl_C", (PC, Mat), (pc, C)); 17973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1798863406b8SStefano Zampini } 1799863406b8SStefano Zampini 1800d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1801d71ae5a4SJacob Faibussowitsch { 18026bf688a0SCe Qin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 18036bf688a0SCe Qin PetscBool ishypre; 18046bf688a0SCe Qin PetscInt i; 18056bf688a0SCe Qin 18064d86920dSPierre Jolivet PetscFunctionBegin; 18079566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 18089566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 18096bf688a0SCe Qin for (i = 0; i < 3; ++i) { 18109566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[i])); 18119566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[i])); 18126bf688a0SCe Qin } 18136bf688a0SCe Qin 18146bf688a0SCe Qin jac->dim = dim; 18156bf688a0SCe Qin if (RT_PiFull) { 18169566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_PiFull, MATHYPRE, &ishypre)); 18176bf688a0SCe Qin if (ishypre) { 18189566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_PiFull)); 18196bf688a0SCe Qin jac->RT_PiFull = RT_PiFull; 18206bf688a0SCe Qin } else { 18219566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_PiFull)); 18226bf688a0SCe Qin } 18236bf688a0SCe Qin } 18246bf688a0SCe Qin if (RT_Pi) { 18256bf688a0SCe Qin for (i = 0; i < dim; ++i) { 18266bf688a0SCe Qin if (RT_Pi[i]) { 18279566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_Pi[i], MATHYPRE, &ishypre)); 18286bf688a0SCe Qin if (ishypre) { 18299566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_Pi[i])); 18306bf688a0SCe Qin jac->RT_Pi[i] = RT_Pi[i]; 18316bf688a0SCe Qin } else { 18329566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_Pi[i])); 18336bf688a0SCe Qin } 18346bf688a0SCe Qin } 18356bf688a0SCe Qin } 18366bf688a0SCe Qin } 18376bf688a0SCe Qin if (ND_PiFull) { 18389566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_PiFull, MATHYPRE, &ishypre)); 18396bf688a0SCe Qin if (ishypre) { 18409566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_PiFull)); 18416bf688a0SCe Qin jac->ND_PiFull = ND_PiFull; 18426bf688a0SCe Qin } else { 18439566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_PiFull)); 18446bf688a0SCe Qin } 18456bf688a0SCe Qin } 18466bf688a0SCe Qin if (ND_Pi) { 18476bf688a0SCe Qin for (i = 0; i < dim; ++i) { 18486bf688a0SCe Qin if (ND_Pi[i]) { 18499566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_Pi[i], MATHYPRE, &ishypre)); 18506bf688a0SCe Qin if (ishypre) { 18519566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_Pi[i])); 18526bf688a0SCe Qin jac->ND_Pi[i] = ND_Pi[i]; 18536bf688a0SCe Qin } else { 18549566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_Pi[i])); 18556bf688a0SCe Qin } 18566bf688a0SCe Qin } 18576bf688a0SCe Qin } 18586bf688a0SCe Qin } 18593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18606bf688a0SCe Qin } 18616bf688a0SCe Qin 18626bf688a0SCe Qin /*@ 1863f1580f4eSBarry Smith PCHYPRESetInterpolations - Set interpolation matrices for `PCHYPRE` type of ams or ads 18646bf688a0SCe Qin 1865c3339decSBarry Smith Collective 18666bf688a0SCe Qin 18676bf688a0SCe Qin Input Parameters: 18686bf688a0SCe Qin + pc - the preconditioning context 18692fe279fdSBarry Smith . dim - the dimension of the problem, only used in AMS 18702fe279fdSBarry Smith . RT_PiFull - Raviart-Thomas interpolation matrix 18712fe279fdSBarry Smith . RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix 18722fe279fdSBarry Smith . ND_PiFull - Nedelec interpolation matrix 18736bf688a0SCe Qin - ND_Pi - x/y/z component of Nedelec interpolation matrix 18746bf688a0SCe Qin 1875f1580f4eSBarry Smith Level: intermediate 1876f1580f4eSBarry Smith 187795452b02SPatrick Sanan Notes: 187895452b02SPatrick Sanan For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL. 1879147403d9SBarry Smith 18806bf688a0SCe Qin For ADS, both type of interpolation matrices are needed. 1881147403d9SBarry Smith 1882feefa0e1SJacob Faibussowitsch Developer Notes: 1883f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 18846bf688a0SCe Qin 1885562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE` 18866bf688a0SCe Qin @*/ 1887d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1888d71ae5a4SJacob Faibussowitsch { 18896bf688a0SCe Qin PetscInt i; 18906bf688a0SCe Qin 18916bf688a0SCe Qin PetscFunctionBegin; 18926bf688a0SCe Qin PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 18936bf688a0SCe Qin if (RT_PiFull) { 18946bf688a0SCe Qin PetscValidHeaderSpecific(RT_PiFull, MAT_CLASSID, 3); 18956bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_PiFull, 3); 18966bf688a0SCe Qin } 18976bf688a0SCe Qin if (RT_Pi) { 18984f572ea9SToby Isaac PetscAssertPointer(RT_Pi, 4); 18996bf688a0SCe Qin for (i = 0; i < dim; ++i) { 19006bf688a0SCe Qin if (RT_Pi[i]) { 19016bf688a0SCe Qin PetscValidHeaderSpecific(RT_Pi[i], MAT_CLASSID, 4); 19026bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_Pi[i], 4); 19036bf688a0SCe Qin } 19046bf688a0SCe Qin } 19056bf688a0SCe Qin } 19066bf688a0SCe Qin if (ND_PiFull) { 19076bf688a0SCe Qin PetscValidHeaderSpecific(ND_PiFull, MAT_CLASSID, 5); 19086bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_PiFull, 5); 19096bf688a0SCe Qin } 19106bf688a0SCe Qin if (ND_Pi) { 19114f572ea9SToby Isaac PetscAssertPointer(ND_Pi, 6); 19126bf688a0SCe Qin for (i = 0; i < dim; ++i) { 19136bf688a0SCe Qin if (ND_Pi[i]) { 19146bf688a0SCe Qin PetscValidHeaderSpecific(ND_Pi[i], MAT_CLASSID, 6); 19156bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_Pi[i], 6); 19166bf688a0SCe Qin } 19176bf688a0SCe Qin } 19186bf688a0SCe Qin } 1919cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetInterpolations_C", (PC, PetscInt, Mat, Mat[], Mat, Mat[]), (pc, dim, RT_PiFull, RT_Pi, ND_PiFull, ND_Pi)); 19203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19216bf688a0SCe Qin } 19226bf688a0SCe Qin 1923d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha) 1924d71ae5a4SJacob Faibussowitsch { 19254cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 19265ac14e1cSStefano Zampini PetscBool ishypre; 19274cb006feSStefano Zampini 19284cb006feSStefano Zampini PetscFunctionBegin; 19299566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 19305ac14e1cSStefano Zampini if (ishypre) { 19315ac14e1cSStefano Zampini if (isalpha) { 19329566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 19339566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 19345ac14e1cSStefano Zampini jac->alpha_Poisson = A; 19355ac14e1cSStefano Zampini } else { 19365ac14e1cSStefano Zampini if (A) { 19379566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 19385ac14e1cSStefano Zampini } else { 19395ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 19405ac14e1cSStefano Zampini } 19419566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 19425ac14e1cSStefano Zampini jac->beta_Poisson = A; 19435ac14e1cSStefano Zampini } 19445ac14e1cSStefano Zampini } else { 19455ac14e1cSStefano Zampini if (isalpha) { 19469566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 19479566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->alpha_Poisson)); 19485ac14e1cSStefano Zampini } else { 19495ac14e1cSStefano Zampini if (A) { 19509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 19519566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->beta_Poisson)); 19525ac14e1cSStefano Zampini } else { 19539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 19545ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 19555ac14e1cSStefano Zampini } 19565ac14e1cSStefano Zampini } 19575ac14e1cSStefano Zampini } 19583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19594cb006feSStefano Zampini } 19604cb006feSStefano Zampini 19614cb006feSStefano Zampini /*@ 1962f1580f4eSBarry Smith PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix for `PCHYPRE` of type ams 19634cb006feSStefano Zampini 1964c3339decSBarry Smith Collective 19654cb006feSStefano Zampini 19664cb006feSStefano Zampini Input Parameters: 19674cb006feSStefano Zampini + pc - the preconditioning context 19684cb006feSStefano Zampini - A - the matrix 19694cb006feSStefano Zampini 19704cb006feSStefano Zampini Level: intermediate 19714cb006feSStefano Zampini 1972f1580f4eSBarry Smith Note: 197395452b02SPatrick Sanan A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 19744cb006feSStefano Zampini 1975feefa0e1SJacob Faibussowitsch Developer Notes: 1976f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1977f1580f4eSBarry Smith 1978f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetAlphaPoissonMatrix()` 1979f1580f4eSBarry Smith 1980562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()` 19814cb006feSStefano Zampini @*/ 1982d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 1983d71ae5a4SJacob Faibussowitsch { 19844cb006feSStefano Zampini PetscFunctionBegin; 19854cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 19864cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 19874cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 1988cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_TRUE)); 19893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19904cb006feSStefano Zampini } 19914cb006feSStefano Zampini 19924cb006feSStefano Zampini /*@ 1993f1580f4eSBarry Smith PCHYPRESetBetaPoissonMatrix - Set Poisson matrix for `PCHYPRE` of type ams 19944cb006feSStefano Zampini 1995c3339decSBarry Smith Collective 19964cb006feSStefano Zampini 19974cb006feSStefano Zampini Input Parameters: 19984cb006feSStefano Zampini + pc - the preconditioning context 1999f1580f4eSBarry Smith - A - the matrix, or NULL to turn it off 20004cb006feSStefano Zampini 20014cb006feSStefano Zampini Level: intermediate 20024cb006feSStefano Zampini 2003f1580f4eSBarry Smith Note: 200495452b02SPatrick Sanan A should be obtained by discretizing the Poisson problem with linear finite elements. 20054cb006feSStefano Zampini 2006feefa0e1SJacob Faibussowitsch Developer Notes: 2007f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 2008f1580f4eSBarry Smith 2009f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSPCHYPRESetBetaPoissonMatrix()` 2010f1580f4eSBarry Smith 2011562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 20124cb006feSStefano Zampini @*/ 2013d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 2014d71ae5a4SJacob Faibussowitsch { 20154cb006feSStefano Zampini PetscFunctionBegin; 20164cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 20174cb006feSStefano Zampini if (A) { 20184cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 20194cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 20204cb006feSStefano Zampini } 2021cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_FALSE)); 20223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20234cb006feSStefano Zampini } 20244cb006feSStefano Zampini 2025d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc, Vec ozz, Vec zoz, Vec zzo) 2026d71ae5a4SJacob Faibussowitsch { 20274cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 20284cb006feSStefano Zampini 20294cb006feSStefano Zampini PetscFunctionBegin; 20304cb006feSStefano Zampini /* throw away any vector if already set */ 20319566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 20329566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 20339566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 20349566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(ozz->map, &jac->constants[0])); 20359566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(ozz, jac->constants[0])); 20369566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zoz->map, &jac->constants[1])); 20379566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zoz, jac->constants[1])); 20385ac14e1cSStefano Zampini jac->dim = 2; 20394cb006feSStefano Zampini if (zzo) { 20409566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zzo->map, &jac->constants[2])); 20419566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zzo, jac->constants[2])); 20425ac14e1cSStefano Zampini jac->dim++; 20434cb006feSStefano Zampini } 20443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20454cb006feSStefano Zampini } 20464cb006feSStefano Zampini 20474cb006feSStefano Zampini /*@ 2048f1580f4eSBarry Smith PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis for `PCHYPRE` of type ams 20494cb006feSStefano Zampini 2050c3339decSBarry Smith Collective 20514cb006feSStefano Zampini 20524cb006feSStefano Zampini Input Parameters: 20534cb006feSStefano Zampini + pc - the preconditioning context 20542fe279fdSBarry Smith . ozz - vector representing (1,0,0) (or (1,0) in 2D) 20552fe279fdSBarry Smith . zoz - vector representing (0,1,0) (or (0,1) in 2D) 20564cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 20574cb006feSStefano Zampini 20584cb006feSStefano Zampini Level: intermediate 20594cb006feSStefano Zampini 2060feefa0e1SJacob Faibussowitsch Developer Notes: 2061f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetEdgeConstantVectors()` 2062f1580f4eSBarry Smith 2063562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 20644cb006feSStefano Zampini @*/ 2065d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 2066d71ae5a4SJacob Faibussowitsch { 20674cb006feSStefano Zampini PetscFunctionBegin; 20684cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 20694cb006feSStefano Zampini PetscValidHeaderSpecific(ozz, VEC_CLASSID, 2); 20704cb006feSStefano Zampini PetscValidHeaderSpecific(zoz, VEC_CLASSID, 3); 20714cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo, VEC_CLASSID, 4); 20724cb006feSStefano Zampini PetscCheckSameComm(pc, 1, ozz, 2); 20734cb006feSStefano Zampini PetscCheckSameComm(pc, 1, zoz, 3); 20744cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc, 1, zzo, 4); 2075cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetEdgeConstantVectors_C", (PC, Vec, Vec, Vec), (pc, ozz, zoz, zzo)); 20763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20774cb006feSStefano Zampini } 20784cb006feSStefano Zampini 2079d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREAMSSetInteriorNodes_HYPRE(PC pc, Vec interior) 2080d71ae5a4SJacob Faibussowitsch { 2081be14dc20SKerry Key PC_HYPRE *jac = (PC_HYPRE *)pc->data; 2082be14dc20SKerry Key 2083be14dc20SKerry Key PetscFunctionBegin; 2084be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 2085be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCreate(interior->map, &jac->interior)); 2086be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCopy(interior, jac->interior)); 2087be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_TRUE; 20883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2089be14dc20SKerry Key } 2090be14dc20SKerry Key 2091be14dc20SKerry Key /*@ 2092f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes - Set the list of interior nodes to a zero-conductivity region for `PCHYPRE` of type ams 2093be14dc20SKerry Key 2094c3339decSBarry Smith Collective 2095be14dc20SKerry Key 2096be14dc20SKerry Key Input Parameters: 2097be14dc20SKerry Key + pc - the preconditioning context 2098be14dc20SKerry Key - interior - vector. node is interior if its entry in the array is 1.0. 2099be14dc20SKerry Key 2100be14dc20SKerry Key Level: intermediate 2101be14dc20SKerry Key 2102be14dc20SKerry Key Note: 2103f1580f4eSBarry Smith This calls `HYPRE_AMSSetInteriorNodes()` 2104f1580f4eSBarry Smith 2105feefa0e1SJacob Faibussowitsch Developer Notes: 2106f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetInteriorNodes()` 2107f1580f4eSBarry Smith 2108562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 2109be14dc20SKerry Key @*/ 2110d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREAMSSetInteriorNodes(PC pc, Vec interior) 2111d71ae5a4SJacob Faibussowitsch { 2112be14dc20SKerry Key PetscFunctionBegin; 2113be14dc20SKerry Key PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2114be14dc20SKerry Key PetscValidHeaderSpecific(interior, VEC_CLASSID, 2); 2115be14dc20SKerry Key PetscCheckSameComm(pc, 1, interior, 2); 2116be14dc20SKerry Key PetscTryMethod(pc, "PCHYPREAMSSetInteriorNodes_C", (PC, Vec), (pc, interior)); 21173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2118be14dc20SKerry Key } 2119be14dc20SKerry Key 2120d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2121d71ae5a4SJacob Faibussowitsch { 21224cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 21234cb006feSStefano Zampini Vec tv; 21244cb006feSStefano Zampini PetscInt i; 21254cb006feSStefano Zampini 21264cb006feSStefano Zampini PetscFunctionBegin; 21274cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 21289566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 21299566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 21309566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 21315ac14e1cSStefano Zampini jac->dim = dim; 21325ac14e1cSStefano Zampini 21334cb006feSStefano Zampini /* compute IJ vector for coordinates */ 21349566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)pc), &tv)); 21359566063dSJacob Faibussowitsch PetscCall(VecSetType(tv, VECSTANDARD)); 21369566063dSJacob Faibussowitsch PetscCall(VecSetSizes(tv, nloc, PETSC_DECIDE)); 21374cb006feSStefano Zampini for (i = 0; i < dim; i++) { 21384cb006feSStefano Zampini PetscScalar *array; 21394cb006feSStefano Zampini PetscInt j; 21404cb006feSStefano Zampini 21419566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(tv->map, &jac->coords[i])); 21429566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(tv, &array)); 21436ea7df73SStefano Zampini for (j = 0; j < nloc; j++) array[j] = coords[j * dim + i]; 21449566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(tv, &array)); 21459566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(tv, jac->coords[i])); 21464cb006feSStefano Zampini } 21479566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tv)); 21483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21494cb006feSStefano Zampini } 21504cb006feSStefano Zampini 2151d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREGetType_HYPRE(PC pc, const char *name[]) 2152d71ae5a4SJacob Faibussowitsch { 215316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 215416d9e3a6SLisandro Dalcin 215516d9e3a6SLisandro Dalcin PetscFunctionBegin; 215616d9e3a6SLisandro Dalcin *name = jac->hypre_type; 21573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 215816d9e3a6SLisandro Dalcin } 215916d9e3a6SLisandro Dalcin 2160d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetType_HYPRE(PC pc, const char name[]) 2161d71ae5a4SJacob Faibussowitsch { 216216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 2163ace3abfcSBarry Smith PetscBool flag; 216416d9e3a6SLisandro Dalcin 216516d9e3a6SLisandro Dalcin PetscFunctionBegin; 216616d9e3a6SLisandro Dalcin if (jac->hypre_type) { 21679566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, name, &flag)); 21685f80ce2aSJacob Faibussowitsch PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "Cannot reset the HYPRE preconditioner type once it has been set"); 21693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 217016d9e3a6SLisandro Dalcin } else { 21719566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->hypre_type)); 217216d9e3a6SLisandro Dalcin } 217316d9e3a6SLisandro Dalcin 217416d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 217516d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 217616d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 217716d9e3a6SLisandro Dalcin 21783c61a47dSLukas PetscCall(PetscStrcmp("ilu", jac->hypre_type, &flag)); 21793c61a47dSLukas if (flag) { 21803c61a47dSLukas PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 21813c61a47dSLukas PetscCallExternal(HYPRE_ILUCreate, &jac->hsolver); 21823c61a47dSLukas pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ILU; 21833c61a47dSLukas pc->ops->view = PCView_HYPRE_ILU; 21843c61a47dSLukas jac->destroy = HYPRE_ILUDestroy; 21853c61a47dSLukas jac->setup = HYPRE_ILUSetup; 21863c61a47dSLukas jac->solve = HYPRE_ILUSolve; 21873c61a47dSLukas jac->factorrowsize = PETSC_DEFAULT; 21883c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 21893c61a47dSLukas } 21903c61a47dSLukas 21919566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("pilut", jac->hypre_type, &flag)); 219216d9e3a6SLisandro Dalcin if (flag) { 21939566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2194792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRPilutCreate, jac->comm_hypre, &jac->hsolver); 219516d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 219616d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 219716d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 219816d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 219916d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 220016d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 22013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 220216d9e3a6SLisandro Dalcin } 22039566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("euclid", jac->hypre_type, &flag)); 2204db966c6cSHong Zhang if (flag) { 22054e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 22067de69702SBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Hypre Euclid does not support 64-bit indices"); 22078bf83915SBarry Smith #endif 22089566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2209792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidCreate, jac->comm_hypre, &jac->hsolver); 2210db966c6cSHong Zhang pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 2211db966c6cSHong Zhang pc->ops->view = PCView_HYPRE_Euclid; 2212db966c6cSHong Zhang jac->destroy = HYPRE_EuclidDestroy; 2213db966c6cSHong Zhang jac->setup = HYPRE_EuclidSetup; 2214db966c6cSHong Zhang jac->solve = HYPRE_EuclidSolve; 2215db966c6cSHong Zhang jac->factorrowsize = PETSC_DEFAULT; 2216db966c6cSHong Zhang jac->eu_level = PETSC_DEFAULT; /* default */ 22173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2218db966c6cSHong Zhang } 22199566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("parasails", jac->hypre_type, &flag)); 222016d9e3a6SLisandro Dalcin if (flag) { 22219566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2222792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsCreate, jac->comm_hypre, &jac->hsolver); 222316d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 222416d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 222516d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 222616d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 222716d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 222816d9e3a6SLisandro Dalcin /* initialize */ 222916d9e3a6SLisandro Dalcin jac->nlevels = 1; 22308966356dSPierre Jolivet jac->threshold = .1; 223116d9e3a6SLisandro Dalcin jac->filter = .1; 223216d9e3a6SLisandro Dalcin jac->loadbal = 0; 22332fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int)PETSC_TRUE; 22342fa5cd67SKarl Rupp else jac->logging = (int)PETSC_FALSE; 22352fa5cd67SKarl Rupp 223616d9e3a6SLisandro Dalcin jac->ruse = (int)PETSC_FALSE; 223716d9e3a6SLisandro Dalcin jac->symt = 0; 2238792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 2239792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 2240792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 2241792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 2242792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 2243792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 22443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 224516d9e3a6SLisandro Dalcin } 22469566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("boomeramg", jac->hypre_type, &flag)); 224716d9e3a6SLisandro Dalcin if (flag) { 2248792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGCreate, &jac->hsolver); 224916d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 225016d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 225116d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 225216d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 225385245615SPierre Jolivet pc->ops->matapply = PCMatApply_HYPRE_BoomerAMG; 22549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", PCGetInterpolations_BoomerAMG)); 22559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", PCGetCoarseOperators_BoomerAMG)); 225642e5ec60SJeff-Hadley PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetCFMarkers_C", PCHYPREGetCFMarkers_BoomerAMG)); 225716d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 225816d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 225916d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 226016d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 226116d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 226216d9e3a6SLisandro Dalcin jac->cycletype = 1; 226316d9e3a6SLisandro Dalcin jac->maxlevels = 25; 226416d9e3a6SLisandro Dalcin jac->maxiter = 1; 22658f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 226616d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 226716d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 226816d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 226916d9e3a6SLisandro Dalcin jac->coarsentype = 6; 227016d9e3a6SLisandro Dalcin jac->measuretype = 0; 22710f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 22726a251517SEike Mueller jac->smoothtype = -1; /* Not set by default */ 2273b9eb5777SEike Mueller jac->smoothnumlevels = 25; 22741810e44eSEike Mueller jac->eu_level = 0; 22751810e44eSEike Mueller jac->eu_droptolerance = 0; 22761810e44eSEike Mueller jac->eu_bj = 0; 2277589dcaf0SStefano Zampini jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */ 22780f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 227916d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 228016d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 228116d9e3a6SLisandro Dalcin jac->relaxorder = 1; 22820f1074feSSatish Balay jac->interptype = 0; 2283589dcaf0SStefano Zampini jac->Rtype = 0; 2284589dcaf0SStefano Zampini jac->Rstrongthreshold = 0.25; 2285589dcaf0SStefano Zampini jac->Rfilterthreshold = 0.0; 2286589dcaf0SStefano Zampini jac->Adroptype = -1; 2287589dcaf0SStefano Zampini jac->Adroptol = 0.0; 22880f1074feSSatish Balay jac->agg_nl = 0; 22896ea7df73SStefano Zampini jac->agg_interptype = 4; 22900f1074feSSatish Balay jac->pmax = 0; 22910f1074feSSatish Balay jac->truncfactor = 0.0; 22920f1074feSSatish Balay jac->agg_num_paths = 1; 2293589dcaf0SStefano Zampini jac->maxc = 9; 2294589dcaf0SStefano Zampini jac->minc = 1; 229522e51d31SStefano Zampini jac->nodal_coarsening = 0; 229622e51d31SStefano Zampini jac->nodal_coarsening_diag = 0; 229722e51d31SStefano Zampini jac->vec_interp_variant = 0; 229822e51d31SStefano Zampini jac->vec_interp_qmax = 0; 229922e51d31SStefano Zampini jac->vec_interp_smooth = PETSC_FALSE; 230022e51d31SStefano Zampini jac->interp_refine = 0; 23018f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 23028f87f92bSBarry Smith jac->nodal_relax_levels = 1; 23036ea7df73SStefano Zampini jac->rap2 = 0; 23046ea7df73SStefano Zampini 23056ea7df73SStefano Zampini /* GPU defaults 23066ea7df73SStefano Zampini from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options 23076ea7df73SStefano Zampini and /src/parcsr_ls/par_amg.c */ 23086ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 23096ea7df73SStefano Zampini jac->keeptranspose = PETSC_TRUE; 23106ea7df73SStefano Zampini jac->mod_rap2 = 1; 23116ea7df73SStefano Zampini jac->coarsentype = 8; 23126ea7df73SStefano Zampini jac->relaxorder = 0; 23136ea7df73SStefano Zampini jac->interptype = 6; 23146ea7df73SStefano Zampini jac->relaxtype[0] = 18; 23156ea7df73SStefano Zampini jac->relaxtype[1] = 18; 23166ea7df73SStefano Zampini jac->agg_interptype = 7; 23176ea7df73SStefano Zampini #else 23186ea7df73SStefano Zampini jac->keeptranspose = PETSC_FALSE; 23196ea7df73SStefano Zampini jac->mod_rap2 = 0; 23206ea7df73SStefano Zampini #endif 2321792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 2322792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 2323792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 2324792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 2325792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 2326792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 2327792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 2328792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 2329792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 2330792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 2331792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 2332792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 2333792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggInterpType, jac->hsolver, jac->agg_interptype); 2334792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 2335792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 2336792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, jac->relaxtype[0]); /* defaults coarse to 9 */ 2337792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps, jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */ 2338792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 2339792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 23406ea7df73SStefano Zampini /* GPU */ 23416ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 2342792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 2343792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRAP2, jac->hsolver, jac->rap2); 2344792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetModuleRAP2, jac->hsolver, jac->mod_rap2); 23456ea7df73SStefano Zampini #endif 23466ea7df73SStefano Zampini 2347589dcaf0SStefano Zampini /* AIR */ 23486ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 2349792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 2350792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 2351792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 2352792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 2353792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 23546ea7df73SStefano Zampini #endif 23553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 235616d9e3a6SLisandro Dalcin } 23579566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ams", jac->hypre_type, &flag)); 23584cb006feSStefano Zampini if (flag) { 23593ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_AMSCreate, &jac->hsolver); 23604cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 23614cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 23624cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 23634cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 23644cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 23654cb006feSStefano Zampini jac->coords[0] = NULL; 23664cb006feSStefano Zampini jac->coords[1] = NULL; 23674cb006feSStefano Zampini jac->coords[2] = NULL; 2368be14dc20SKerry Key jac->interior = NULL; 23694cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 2370863406b8SStefano Zampini jac->as_print = 0; 2371863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2372863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 23734cb006feSStefano Zampini jac->ams_cycle_type = 13; 23744cb006feSStefano Zampini /* Smoothing options */ 2375863406b8SStefano Zampini jac->as_relax_type = 2; 2376863406b8SStefano Zampini jac->as_relax_times = 1; 2377863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2378863406b8SStefano Zampini jac->as_omega = 1.0; 23794cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2380863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2381863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 23820bdd8552SBarry Smith jac->as_amg_alpha_opts[2] = 6; 2383863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2384863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2385863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 23864cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2387863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2388863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 23890bdd8552SBarry Smith jac->as_amg_beta_opts[2] = 6; 2390863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2391863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2392863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2393792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 2394792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 2395792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2396792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 23979371c9d4SSatish Balay PetscCallExternal(HYPRE_AMSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2398792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2399863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2400863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 24019371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2402a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2403792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2404863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2405863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 24069371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2407a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 240823df4f25SStefano Zampini /* Zero conductivity */ 240923df4f25SStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 241023df4f25SStefano Zampini jac->ams_beta_is_zero_part = PETSC_FALSE; 24113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24124cb006feSStefano Zampini } 24139566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ads", jac->hypre_type, &flag)); 2414863406b8SStefano Zampini if (flag) { 24153ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_ADSCreate, &jac->hsolver); 2416863406b8SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ADS; 2417863406b8SStefano Zampini pc->ops->view = PCView_HYPRE_ADS; 2418863406b8SStefano Zampini jac->destroy = HYPRE_ADSDestroy; 2419863406b8SStefano Zampini jac->setup = HYPRE_ADSSetup; 2420863406b8SStefano Zampini jac->solve = HYPRE_ADSSolve; 2421863406b8SStefano Zampini jac->coords[0] = NULL; 2422863406b8SStefano Zampini jac->coords[1] = NULL; 2423863406b8SStefano Zampini jac->coords[2] = NULL; 2424863406b8SStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */ 2425863406b8SStefano Zampini jac->as_print = 0; 2426863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2427863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 2428863406b8SStefano Zampini jac->ads_cycle_type = 13; 2429863406b8SStefano Zampini /* Smoothing options */ 2430863406b8SStefano Zampini jac->as_relax_type = 2; 2431863406b8SStefano Zampini jac->as_relax_times = 1; 2432863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2433863406b8SStefano Zampini jac->as_omega = 1.0; 2434863406b8SStefano Zampini /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2435863406b8SStefano Zampini jac->ams_cycle_type = 14; 2436863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2437863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 2438863406b8SStefano Zampini jac->as_amg_alpha_opts[2] = 6; 2439863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2440863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2441863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 2442863406b8SStefano Zampini /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2443863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2444863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 2445863406b8SStefano Zampini jac->as_amg_beta_opts[2] = 6; 2446863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2447863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2448863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2449792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 2450792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 2451792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2452792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 24539371c9d4SSatish Balay PetscCallExternal(HYPRE_ADSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2454792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMG coarsen type */ 2455863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2456863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2457863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 24589371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2459a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2460792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2461863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2462863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 24639371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2464a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 24653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2466863406b8SStefano Zampini } 24679566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 24682fa5cd67SKarl Rupp 24690298fd71SBarry Smith jac->hypre_type = NULL; 247098921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams", name); 247116d9e3a6SLisandro Dalcin } 247216d9e3a6SLisandro Dalcin 247316d9e3a6SLisandro Dalcin /* 247416d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 247516d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 247616d9e3a6SLisandro Dalcin */ 2477ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE(PC pc, PetscOptionItems *PetscOptionsObject) 2478d71ae5a4SJacob Faibussowitsch { 24794ddd07fcSJed Brown PetscInt indx; 24803c61a47dSLukas const char *type[] = {"ilu", "euclid", "pilut", "parasails", "boomeramg", "ams", "ads"}; 2481ace3abfcSBarry Smith PetscBool flg; 248216d9e3a6SLisandro Dalcin 248316d9e3a6SLisandro Dalcin PetscFunctionBegin; 2484d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE preconditioner options"); 2485dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_type", "HYPRE preconditioner type", "PCHYPRESetType", type, PETSC_STATIC_ARRAY_LENGTH(type), "boomeramg", &indx, &flg)); 248616d9e3a6SLisandro Dalcin if (flg) { 24879566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc, type[indx])); 248802a17cd4SBarry Smith } else { 24899566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc, "boomeramg")); 249016d9e3a6SLisandro Dalcin } 2491dbbe0bcdSBarry Smith PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject); 2492d0609cedSBarry Smith PetscOptionsHeadEnd(); 24933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 249416d9e3a6SLisandro Dalcin } 249516d9e3a6SLisandro Dalcin 2496cc4c1da9SBarry Smith /*@ 249716d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 249816d9e3a6SLisandro Dalcin 249916d9e3a6SLisandro Dalcin Input Parameters: 250016d9e3a6SLisandro Dalcin + pc - the preconditioner context 2501db966c6cSHong Zhang - name - either euclid, pilut, parasails, boomeramg, ams, ads 250216d9e3a6SLisandro Dalcin 2503f1580f4eSBarry Smith Options Database Key: 2504feefa0e1SJacob Faibussowitsch . pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 250516d9e3a6SLisandro Dalcin 250616d9e3a6SLisandro Dalcin Level: intermediate 250716d9e3a6SLisandro Dalcin 2508562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRE` 250916d9e3a6SLisandro Dalcin @*/ 2510d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetType(PC pc, const char name[]) 2511d71ae5a4SJacob Faibussowitsch { 251216d9e3a6SLisandro Dalcin PetscFunctionBegin; 25130700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 25144f572ea9SToby Isaac PetscAssertPointer(name, 2); 2515cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetType_C", (PC, const char[]), (pc, name)); 25163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 251716d9e3a6SLisandro Dalcin } 251816d9e3a6SLisandro Dalcin 251942e5ec60SJeff-Hadley /*@C 252042e5ec60SJeff-Hadley PCHYPREGetCFMarkers - Gets CF marker arrays for all levels (except the finest level) 252142e5ec60SJeff-Hadley 252242e5ec60SJeff-Hadley Logically Collective 252342e5ec60SJeff-Hadley 252442e5ec60SJeff-Hadley Input Parameter: 252542e5ec60SJeff-Hadley . pc - the preconditioner context 252642e5ec60SJeff-Hadley 252742e5ec60SJeff-Hadley Output Parameters: 252842e5ec60SJeff-Hadley + n_per_level - the number of nodes per level (size of `num_levels`) 252942e5ec60SJeff-Hadley - CFMarkers - the Coarse/Fine Boolean arrays (size of `num_levels` - 1) 253042e5ec60SJeff-Hadley 253142e5ec60SJeff-Hadley Note: 253242e5ec60SJeff-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. 253342e5ec60SJeff-Hadley 253442e5ec60SJeff-Hadley Level: advanced 253542e5ec60SJeff-Hadley 253642e5ec60SJeff-Hadley .seealso: [](ch_ksp), `PC`, `PCMG`, `PCMGGetRestriction()`, `PCMGSetInterpolation()`, `PCMGGetRScale()`, `PCMGGetInterpolation()`, `PCGetInterpolations()` 253742e5ec60SJeff-Hadley @*/ 253842e5ec60SJeff-Hadley PetscErrorCode PCHYPREGetCFMarkers(PC pc, PetscInt *n_per_level[], PetscBT *CFMarkers[]) 253942e5ec60SJeff-Hadley { 254042e5ec60SJeff-Hadley PetscFunctionBegin; 254142e5ec60SJeff-Hadley PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 254242e5ec60SJeff-Hadley PetscAssertPointer(n_per_level, 2); 254342e5ec60SJeff-Hadley PetscAssertPointer(CFMarkers, 3); 254442e5ec60SJeff-Hadley PetscUseMethod(pc, "PCHYPREGetCFMarkers_C", (PC, PetscInt *[], PetscBT *[]), (pc, n_per_level, CFMarkers)); 254542e5ec60SJeff-Hadley PetscFunctionReturn(PETSC_SUCCESS); 254642e5ec60SJeff-Hadley } 254742e5ec60SJeff-Hadley 2548cc4c1da9SBarry Smith /*@ 254916d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 255016d9e3a6SLisandro Dalcin 255116d9e3a6SLisandro Dalcin Input Parameter: 255216d9e3a6SLisandro Dalcin . pc - the preconditioner context 255316d9e3a6SLisandro Dalcin 255416d9e3a6SLisandro Dalcin Output Parameter: 2555db966c6cSHong Zhang . name - either euclid, pilut, parasails, boomeramg, ams, ads 255616d9e3a6SLisandro Dalcin 255716d9e3a6SLisandro Dalcin Level: intermediate 255816d9e3a6SLisandro Dalcin 2559562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`, `PCHYPRE` 256016d9e3a6SLisandro Dalcin @*/ 2561d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREGetType(PC pc, const char *name[]) 2562d71ae5a4SJacob Faibussowitsch { 256316d9e3a6SLisandro Dalcin PetscFunctionBegin; 25640700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 25654f572ea9SToby Isaac PetscAssertPointer(name, 2); 2566cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPREGetType_C", (PC, const char *[]), (pc, name)); 25673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 256816d9e3a6SLisandro Dalcin } 256916d9e3a6SLisandro Dalcin 2570cc4c1da9SBarry Smith /*@ 2571f1580f4eSBarry Smith PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use on GPUs 2572db6f9c32SMark Adams 2573c3339decSBarry Smith Logically Collective 2574db6f9c32SMark Adams 2575db6f9c32SMark Adams Input Parameters: 2576db6f9c32SMark Adams + pc - the hypre context 2577feefa0e1SJacob Faibussowitsch - name - one of 'cusparse', 'hypre' 2578db6f9c32SMark Adams 2579db6f9c32SMark Adams Options Database Key: 258067b8a455SSatish Balay . -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre 2581db6f9c32SMark Adams 2582db6f9c32SMark Adams Level: intermediate 2583db6f9c32SMark Adams 2584feefa0e1SJacob Faibussowitsch Developer Notes: 2585f1580f4eSBarry Smith How the name starts with `PCMG`, should it not be `PCHYPREBoomerAMG`? 2586db6f9c32SMark Adams 2587562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinGetMatProductAlgorithm()` 2588db6f9c32SMark Adams @*/ 2589d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc, const char name[]) 2590d71ae5a4SJacob Faibussowitsch { 2591db6f9c32SMark Adams PetscFunctionBegin; 2592db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2593cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinSetMatProductAlgorithm_C", (PC, const char[]), (pc, name)); 25943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2595db6f9c32SMark Adams } 2596db6f9c32SMark Adams 2597cc4c1da9SBarry Smith /*@ 2598f1580f4eSBarry Smith PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre to use on GPUs 2599db6f9c32SMark Adams 2600db6f9c32SMark Adams Not Collective 2601db6f9c32SMark Adams 2602db6f9c32SMark Adams Input Parameter: 2603db6f9c32SMark Adams . pc - the multigrid context 2604db6f9c32SMark Adams 2605db6f9c32SMark Adams Output Parameter: 2606db6f9c32SMark Adams . name - one of 'cusparse', 'hypre' 2607db6f9c32SMark Adams 2608db6f9c32SMark Adams Level: intermediate 2609db6f9c32SMark Adams 2610a94f484eSPierre Jolivet .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinSetMatProductAlgorithm()` 2611db6f9c32SMark Adams @*/ 2612d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc, const char *name[]) 2613d71ae5a4SJacob Faibussowitsch { 2614db6f9c32SMark Adams PetscFunctionBegin; 2615db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2616cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinGetMatProductAlgorithm_C", (PC, const char *[]), (pc, name)); 26173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2618db6f9c32SMark Adams } 2619db6f9c32SMark Adams 262016d9e3a6SLisandro Dalcin /*MC 2621f1580f4eSBarry Smith PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre as PETSc `PC` 262216d9e3a6SLisandro Dalcin 262316d9e3a6SLisandro Dalcin Options Database Keys: 2624e1ded407SBarry Smith + -pc_hypre_type - One of `euclid`, `pilut`, `parasails`, `boomeramg`, `ams`, or `ads` 2625f1580f4eSBarry Smith . -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see `HYPRE_BOOMERAMGSetNodal()`) 2626f1580f4eSBarry Smith . -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see `HYPRE_BoomerAMGSetInterpVecVariant()`) 2627e1ded407SBarry Smith - Many others, run with `-pc_type hypre` `-pc_hypre_type XXX` `-help` to see options for the XXX preconditioner 262816d9e3a6SLisandro Dalcin 262916d9e3a6SLisandro Dalcin Level: intermediate 263016d9e3a6SLisandro Dalcin 263195452b02SPatrick Sanan Notes: 2632e1ded407SBarry Smith Apart from `-pc_hypre_type` (for which there is `PCHYPRESetType()`), 263316d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 263449567fc5SPierre Jolivet or with `PetscOptionsSetValue()`, there are no functions to set them) 263516d9e3a6SLisandro Dalcin 2636e1ded407SBarry Smith The options `-pc_hypre_boomeramg_max_iter` and `-pc_hypre_boomeramg_tol` refer to the number of iterations 2637e1ded407SBarry Smith (V-cycles) and tolerance that boomerAMG does EACH time it is called. So for example, if 2638e1ded407SBarry Smith `-pc_hypre_boomeramg_max_iter` is set to 2 then 2-V-cycles are being used to define the preconditioner 2639e1ded407SBarry Smith (`-pc_hypre_boomeramg_tol` should be set to 0.0 - the default - to strictly use a fixed number of 2640e1ded407SBarry Smith iterations per hypre call). `-ksp_max_it` and `-ksp_rtol` STILL determine the total number of iterations 2641e1ded407SBarry Smith and tolerance for the Krylov solver. For example, if `-pc_hypre_boomeramg_max_iter` is 2 and `-ksp_max_it` is 10 2642e1ded407SBarry Smith then AT MOST twenty V-cycles of boomeramg will be used. 264316d9e3a6SLisandro Dalcin 2644e1ded407SBarry Smith Note that the option `-pc_hypre_boomeramg_relax_type_all` defaults to symmetric relaxation 26450f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 2646e1ded407SBarry Smith Otherwise, you may want to use `-pc_hypre_boomeramg_relax_type_all SOR/Jacobi`. 264716d9e3a6SLisandro Dalcin 2648f1580f4eSBarry Smith `MatSetNearNullSpace()` - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use 2649e1ded407SBarry Smith the following two options: `-pc_hypre_boomeramg_nodal_coarsen <n> -pc_hypre_boomeramg_vec_interp_variant <v>` 26500b1a5bd9SEric Chamberland 2651f1580f4eSBarry Smith See `PCPFMG`, `PCSMG`, and `PCSYSPFMG` for access to hypre's other (nonalgebraic) multigrid solvers 2652f1580f4eSBarry Smith 2653e1ded407SBarry Smith For `PCHYPRE` type of `ams` or `ads` auxiliary data must be provided to the preconditioner with `PCHYPRESetDiscreteGradient()`, 2654f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 265549567fc5SPierre Jolivet `PCHYPREAMSSetInteriorNodes()` 2656f1580f4eSBarry Smith 2657e1ded407SBarry 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 2658e1ded407SBarry Smith since it is usually slower, one should use a `KSPType` of `KSPRICHARDSON` 2659e1ded407SBarry Smith (or equivalently `-ksp_type richardson`) to achieve this. Using `KSPPREONLY` will not work since it only applies a single cycle of multigrid. 2660e1ded407SBarry Smith 2661f1580f4eSBarry Smith PETSc provides its own geometric and algebraic multigrid solvers `PCMG` and `PCGAMG`, also see `PCHMG` which is useful for certain multicomponent problems 26629e5bc791SBarry Smith 2663ead8c081SBarry Smith GPU Notes: 2664ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda 2665f1580f4eSBarry Smith Then pass `VECCUDA` vectors and `MATAIJCUSPARSE` matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2666ead8c081SBarry Smith 2667ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip 2668f1580f4eSBarry Smith Then pass `VECHIP` vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2669ead8c081SBarry Smith 2670562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRESetType()`, `PCPFMG`, `PCGAMG`, `PCSYSPFMG`, `PCSMG`, `PCHYPRESetDiscreteGradient()`, 2671f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 2672f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes() 267316d9e3a6SLisandro Dalcin M*/ 267416d9e3a6SLisandro Dalcin 2675d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 2676d71ae5a4SJacob Faibussowitsch { 267716d9e3a6SLisandro Dalcin PC_HYPRE *jac; 267816d9e3a6SLisandro Dalcin 267916d9e3a6SLisandro Dalcin PetscFunctionBegin; 26804dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac)); 26812fa5cd67SKarl Rupp 268216d9e3a6SLisandro Dalcin pc->data = jac; 26838695de01SBarry Smith pc->ops->reset = PCReset_HYPRE; 268416d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 268516d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 268616d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 268716d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 268816d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 26899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", PCHYPRESetType_HYPRE)); 26909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", PCHYPREGetType_HYPRE)); 26919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", PCSetCoordinates_HYPRE)); 26929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", PCHYPRESetDiscreteGradient_HYPRE)); 26939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", PCHYPRESetDiscreteCurl_HYPRE)); 26949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", PCHYPRESetInterpolations_HYPRE)); 26959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", PCHYPRESetEdgeConstantVectors_HYPRE)); 2696be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", PCHYPREAMSSetInteriorNodes_HYPRE)); 26979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", PCHYPRESetPoissonMatrix_HYPRE)); 26989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG)); 26999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG)); 27006ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 27016ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 27029566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 27036ea7df73SStefano Zampini #endif 27046ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 27059566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 27066ea7df73SStefano Zampini #endif 27076ea7df73SStefano Zampini #endif 2708ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 27093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 271016d9e3a6SLisandro Dalcin } 2711ebc551c0SBarry Smith 2712ebc551c0SBarry Smith typedef struct { 271368326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 2714f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 27159e5bc791SBarry Smith 27169e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 27174ddd07fcSJed Brown PetscInt its; 271873dcfd97SStefano Zampini PetscReal tol; 27194ddd07fcSJed Brown PetscInt relax_type; 27204ddd07fcSJed Brown PetscInt rap_type; 27214ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 27224ddd07fcSJed Brown PetscInt max_levels; 27230be8cd64Sftrigaux PetscInt skip_relax; 27240be8cd64Sftrigaux PetscBool print_statistics; 2725ebc551c0SBarry Smith } PC_PFMG; 2726ebc551c0SBarry Smith 2727ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_PFMG(PC pc) 2728d71ae5a4SJacob Faibussowitsch { 2729f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2730ebc551c0SBarry Smith 2731ebc551c0SBarry Smith PetscFunctionBegin; 2732792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 27339566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 27349566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 27353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2736ebc551c0SBarry Smith } 2737ebc551c0SBarry Smith 27389e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi", "Weighted-Jacobi", "symmetric-Red/Black-Gauss-Seidel", "Red/Black-Gauss-Seidel"}; 27399e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin", "non-Galerkin"}; 27409e5bc791SBarry Smith 2741ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_PFMG(PC pc, PetscViewer viewer) 2742d71ae5a4SJacob Faibussowitsch { 2743ace3abfcSBarry Smith PetscBool iascii; 2744f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2745ebc551c0SBarry Smith 2746ebc551c0SBarry Smith PetscFunctionBegin; 27479566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 27489e5bc791SBarry Smith if (iascii) { 27499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE PFMG preconditioning\n")); 275063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 27519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 27529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 27539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " RAP type %s\n", PFMGRAPType[ex->rap_type])); 275463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 275563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max levels %" PetscInt_FMT "\n", ex->max_levels)); 27560be8cd64Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " skip relax %" PetscInt_FMT "\n", ex->skip_relax)); 27579e5bc791SBarry Smith } 27583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2759ebc551c0SBarry Smith } 2760ebc551c0SBarry Smith 2761ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_PFMG(PC pc, PetscOptionItems *PetscOptionsObject) 2762d71ae5a4SJacob Faibussowitsch { 2763f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2764ebc551c0SBarry Smith 2765ebc551c0SBarry Smith PetscFunctionBegin; 2766d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PFMG options"); 27670be8cd64Sftrigaux PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics", "Print statistics", "HYPRE_StructPFMGSetPrintLevel", ex->print_statistics, &ex->print_statistics, NULL)); 27689566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_its", "Number of iterations of PFMG to use as preconditioner", "HYPRE_StructPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2769792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 27709566063dSJacob 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)); 2771792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 27729566063dSJacob 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)); 2773792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 27749e5bc791SBarry Smith 27759566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_max_levels", "Max Levels for MG hierarchy", "HYPRE_StructPFMGSetMaxLevels", ex->max_levels, &ex->max_levels, NULL)); 2776792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 27773b46a515SGlenn Hammond 27789566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_pfmg_tol", "Tolerance of PFMG", "HYPRE_StructPFMGSetTol", ex->tol, &ex->tol, NULL)); 2779792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 2780dd39110bSPierre 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)); 2781792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 2782dd39110bSPierre 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)); 2783792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 27840be8cd64Sftrigaux 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)); 27850be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetSkipRelax, ex->hsolver, ex->skip_relax); 2786d0609cedSBarry Smith PetscOptionsHeadEnd(); 27873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2788ebc551c0SBarry Smith } 2789ebc551c0SBarry Smith 2790ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_PFMG(PC pc, Vec x, Vec y) 2791d71ae5a4SJacob Faibussowitsch { 2792f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2793d9ca1df4SBarry Smith PetscScalar *yy; 2794d9ca1df4SBarry Smith const PetscScalar *xx; 27954ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 27962cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 2797f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 2798f91d8e95SBarry Smith 2799f91d8e95SBarry Smith PetscFunctionBegin; 28009566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 28019566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 28022cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2803f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 2804f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 2805f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 28062cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 28072cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 28082cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 28092cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 28102cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 28112cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2812f91d8e95SBarry Smith 2813f91d8e95SBarry Smith /* copy x values over to hypre */ 2814792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 28159566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2816792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 28179566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2818792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 2819792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2820f91d8e95SBarry Smith 2821f91d8e95SBarry Smith /* copy solution values back to PETSc */ 28229566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2823792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 28249566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 28253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2826f91d8e95SBarry Smith } 2827f91d8e95SBarry Smith 2828d71ae5a4SJacob 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) 2829d71ae5a4SJacob Faibussowitsch { 28309e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG *)pc->data; 28312cf14000SStefano Zampini HYPRE_Int oits; 28329e5bc791SBarry Smith 28339e5bc791SBarry Smith PetscFunctionBegin; 28349566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 2835792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, its * jac->its); 2836792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, rtol); 28379e5bc791SBarry Smith 28389566063dSJacob Faibussowitsch PetscCall(PCApply_PFMG(pc, b, y)); 2839792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGGetNumIterations, jac->hsolver, &oits); 28409e5bc791SBarry Smith *outits = oits; 28419e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 28429e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 2843792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, jac->tol); 2844792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, jac->its); 28453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28469e5bc791SBarry Smith } 28479e5bc791SBarry Smith 2848ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_PFMG(PC pc) 2849d71ae5a4SJacob Faibussowitsch { 28503a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG *)pc->data; 2851f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 2852ace3abfcSBarry Smith PetscBool flg; 28533a32d3dbSGlenn Hammond 28543a32d3dbSGlenn Hammond PetscFunctionBegin; 28559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 285628b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 28573a32d3dbSGlenn Hammond 28583a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 2859792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 2860792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 28610be8cd64Sftrigaux 28620be8cd64Sftrigaux // Print Hypre statistics about the solve process 28630be8cd64Sftrigaux if (ex->print_statistics) PetscCallExternal(HYPRE_StructPFMGSetPrintLevel, ex->hsolver, 3); 28640be8cd64Sftrigaux 28650be8cd64Sftrigaux // The hypre options must be repeated here because the StructPFMG was destroyed and recreated 28660be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 28670be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 28680be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 28690be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 28700be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 28710be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 28720be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 28730be8cd64Sftrigaux 2874792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2875792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetZeroGuess, ex->hsolver); 28763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28773a32d3dbSGlenn Hammond } 28783a32d3dbSGlenn Hammond 2879ebc551c0SBarry Smith /*MC 2880ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 2881ebc551c0SBarry Smith 2882f1580f4eSBarry Smith Options Database Keys: 288367b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner 288467b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve 288567b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve 288667b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG 28879e5bc791SBarry 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 28880be8cd64Sftrigaux . -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 2889f1580f4eSBarry Smith - -pc_pfmg_skip_relax - skip relaxation on certain grids for isotropic problems. This can greatly improve efficiency by eliminating unnecessary relaxations 2890f1580f4eSBarry Smith when the underlying problem is isotropic, one of 0,1 2891f1580f4eSBarry Smith 2892f1580f4eSBarry Smith Level: advanced 2893f91d8e95SBarry Smith 289495452b02SPatrick Sanan Notes: 289595452b02SPatrick Sanan This is for CELL-centered descretizations 28969e5bc791SBarry Smith 2897f1580f4eSBarry Smith See `PCSYSPFMG` for a version suitable for systems of PDEs, and `PCSMG` 28989e5bc791SBarry Smith 2899f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 2900f1580f4eSBarry Smith 2901f1580f4eSBarry Smith This must be used with the `MATHYPRESTRUCT` matrix type. 2902f1580f4eSBarry Smith 2903f1580f4eSBarry Smith This provides only some of the functionality of PFMG, it supports only one block per process defined by a PETSc `DMDA`. 2904f1580f4eSBarry Smith 2905562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESTRUCT`, `PCHYPRE`, `PCGAMG`, `PCSYSPFMG`, `PCSMG` 2906ebc551c0SBarry Smith M*/ 2907ebc551c0SBarry Smith 2908d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 2909d71ae5a4SJacob Faibussowitsch { 2910ebc551c0SBarry Smith PC_PFMG *ex; 2911ebc551c0SBarry Smith 2912ebc551c0SBarry Smith PetscFunctionBegin; 29139371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 291468326731SBarry Smith pc->data = ex; 2915ebc551c0SBarry Smith 29169e5bc791SBarry Smith ex->its = 1; 29179e5bc791SBarry Smith ex->tol = 1.e-8; 29189e5bc791SBarry Smith ex->relax_type = 1; 29199e5bc791SBarry Smith ex->rap_type = 0; 29209e5bc791SBarry Smith ex->num_pre_relax = 1; 29219e5bc791SBarry Smith ex->num_post_relax = 1; 29223b46a515SGlenn Hammond ex->max_levels = 0; 29230be8cd64Sftrigaux ex->skip_relax = 0; 29240be8cd64Sftrigaux ex->print_statistics = PETSC_FALSE; 29259e5bc791SBarry Smith 2926ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 2927ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 2928ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 2929f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 29309e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 293168326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 29322fa5cd67SKarl Rupp 29339566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 2934ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 2935792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 29363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2937ebc551c0SBarry Smith } 2938d851a50bSGlenn Hammond 2939d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 2940d851a50bSGlenn Hammond typedef struct { 2941d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 2942d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 2943d851a50bSGlenn Hammond 2944d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 29454ddd07fcSJed Brown PetscInt its; 294673dcfd97SStefano Zampini PetscReal tol; 29474ddd07fcSJed Brown PetscInt relax_type; 29484ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 2949d851a50bSGlenn Hammond } PC_SysPFMG; 2950d851a50bSGlenn Hammond 2951ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SysPFMG(PC pc) 2952d71ae5a4SJacob Faibussowitsch { 2953d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2954d851a50bSGlenn Hammond 2955d851a50bSGlenn Hammond PetscFunctionBegin; 2956792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 29579566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 29589566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 29593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2960d851a50bSGlenn Hammond } 2961d851a50bSGlenn Hammond 2962d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi", "Red/Black-Gauss-Seidel"}; 2963d851a50bSGlenn Hammond 2964ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SysPFMG(PC pc, PetscViewer viewer) 2965d71ae5a4SJacob Faibussowitsch { 2966ace3abfcSBarry Smith PetscBool iascii; 2967d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2968d851a50bSGlenn Hammond 2969d851a50bSGlenn Hammond PetscFunctionBegin; 29709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 2971d851a50bSGlenn Hammond if (iascii) { 29729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SysPFMG preconditioning\n")); 297363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 29749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 29759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 297663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 2977d851a50bSGlenn Hammond } 29783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2979d851a50bSGlenn Hammond } 2980d851a50bSGlenn Hammond 2981ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_SysPFMG(PC pc, PetscOptionItems *PetscOptionsObject) 2982d71ae5a4SJacob Faibussowitsch { 2983d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2984ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2985d851a50bSGlenn Hammond 2986d851a50bSGlenn Hammond PetscFunctionBegin; 2987d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SysPFMG options"); 29889566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics", "Print statistics", "HYPRE_SStructSysPFMGSetPrintLevel", flg, &flg, NULL)); 298948a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_SStructSysPFMGSetPrintLevel, ex->ss_solver, 3); 29909566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_its", "Number of iterations of SysPFMG to use as preconditioner", "HYPRE_SStructSysPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2991792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, ex->ss_solver, ex->its); 29929566063dSJacob 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)); 2993792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPreRelax, ex->ss_solver, ex->num_pre_relax); 29949566063dSJacob 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)); 2995792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPostRelax, ex->ss_solver, ex->num_post_relax); 2996d851a50bSGlenn Hammond 29979566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_syspfmg_tol", "Tolerance of SysPFMG", "HYPRE_SStructSysPFMGSetTol", ex->tol, &ex->tol, NULL)); 2998792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, ex->ss_solver, ex->tol); 2999dd39110bSPierre 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)); 3000792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetRelaxType, ex->ss_solver, ex->relax_type); 3001d0609cedSBarry Smith PetscOptionsHeadEnd(); 30023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3003d851a50bSGlenn Hammond } 3004d851a50bSGlenn Hammond 3005ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SysPFMG(PC pc, Vec x, Vec y) 3006d71ae5a4SJacob Faibussowitsch { 3007d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 3008d9ca1df4SBarry Smith PetscScalar *yy; 3009d9ca1df4SBarry Smith const PetscScalar *xx; 30104ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 30112cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 3012f4f49eeaSPierre Jolivet Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)pc->pmat->data; 30134ddd07fcSJed Brown PetscInt ordering = mx->dofs_order; 30144ddd07fcSJed Brown PetscInt nvars = mx->nvars; 30154ddd07fcSJed Brown PetscInt part = 0; 30164ddd07fcSJed Brown PetscInt size; 30174ddd07fcSJed Brown PetscInt i; 3018d851a50bSGlenn Hammond 3019d851a50bSGlenn Hammond PetscFunctionBegin; 30209566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 30219566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 30222cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 3023d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 3024d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 3025d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 30262cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 30272cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 30282cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 30292cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 30302cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 30312cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 3032d851a50bSGlenn Hammond 3033d851a50bSGlenn Hammond size = 1; 30342fa5cd67SKarl Rupp for (i = 0; i < 3; i++) size *= (iupper[i] - ilower[i] + 1); 30352fa5cd67SKarl Rupp 3036d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 3037d851a50bSGlenn Hammond if (ordering) { 3038792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 30399566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 3040792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(xx + (size * i))); 30419566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 3042792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 3043792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructMatrixMatvec, 1.0, mx->ss_mat, mx->ss_b, 0.0, mx->ss_x); 3044792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 3045d851a50bSGlenn Hammond 3046d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 30479566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 3048792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(yy + (size * i))); 30499566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 3050a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 3051d851a50bSGlenn Hammond PetscScalar *z; 30524ddd07fcSJed Brown PetscInt j, k; 3053d851a50bSGlenn Hammond 30549566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvars * size, &z)); 3055792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 30569566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 3057d851a50bSGlenn Hammond 3058d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 3059d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 3060d851a50bSGlenn Hammond k = i * nvars; 30612fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) z[j * size + i] = xx[k + j]; 3062d851a50bSGlenn Hammond } 3063792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 30649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 3065792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 3066792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 3067d851a50bSGlenn Hammond 3068d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 30699566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 3070792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 3071d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 3072d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 3073d851a50bSGlenn Hammond k = i * nvars; 30742fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) yy[k + j] = z[j * size + i]; 3075d851a50bSGlenn Hammond } 30769566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 30779566063dSJacob Faibussowitsch PetscCall(PetscFree(z)); 3078d851a50bSGlenn Hammond } 30793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3080d851a50bSGlenn Hammond } 3081d851a50bSGlenn Hammond 3082d71ae5a4SJacob 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) 3083d71ae5a4SJacob Faibussowitsch { 3084d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG *)pc->data; 30852cf14000SStefano Zampini HYPRE_Int oits; 3086d851a50bSGlenn Hammond 3087d851a50bSGlenn Hammond PetscFunctionBegin; 30889566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 3089792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, its * jac->its); 3090792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, rtol); 30919566063dSJacob Faibussowitsch PetscCall(PCApply_SysPFMG(pc, b, y)); 3092792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGGetNumIterations, jac->ss_solver, &oits); 3093d851a50bSGlenn Hammond *outits = oits; 3094d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 3095d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 3096792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, jac->tol); 3097792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, jac->its); 30983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3099d851a50bSGlenn Hammond } 3100d851a50bSGlenn Hammond 3101ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SysPFMG(PC pc) 3102d71ae5a4SJacob Faibussowitsch { 3103d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 3104f4f49eeaSPierre Jolivet Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)pc->pmat->data; 3105ace3abfcSBarry Smith PetscBool flg; 3106d851a50bSGlenn Hammond 3107d851a50bSGlenn Hammond PetscFunctionBegin; 31089566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESSTRUCT, &flg)); 310928b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESSTRUCT with this preconditioner"); 3110d851a50bSGlenn Hammond 3111d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 3112792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 3113792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 3114792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetZeroGuess, ex->ss_solver); 3115792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetup, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 31163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3117d851a50bSGlenn Hammond } 3118d851a50bSGlenn Hammond 3119d851a50bSGlenn Hammond /*MC 3120f1580f4eSBarry Smith PCSYSPFMG - the hypre SysPFMG multigrid solver 3121d851a50bSGlenn Hammond 3122d851a50bSGlenn Hammond Level: advanced 3123d851a50bSGlenn Hammond 3124f1580f4eSBarry Smith Options Database Keys: 312567b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner 312667b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid 312767b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid 312867b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG 312967b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles 3130d851a50bSGlenn Hammond 313195452b02SPatrick Sanan Notes: 3132f1580f4eSBarry Smith See `PCPFMG` for hypre's PFMG that works for a scalar PDE and `PCSMG` 3133f1580f4eSBarry Smith 3134f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 3135f1580f4eSBarry Smith 313695452b02SPatrick Sanan This is for CELL-centered descretizations 3137d851a50bSGlenn Hammond 3138f1580f4eSBarry Smith This must be used with the `MATHYPRESSTRUCT` matrix type. 3139d851a50bSGlenn Hammond 3140f1580f4eSBarry 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`. 3141f1580f4eSBarry Smith 3142562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESSTRUCT`, `PCPFMG`, `PCHYPRE`, `PCGAMG`, `PCSMG` 3143d851a50bSGlenn Hammond M*/ 3144d851a50bSGlenn Hammond 3145d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 3146d71ae5a4SJacob Faibussowitsch { 3147d851a50bSGlenn Hammond PC_SysPFMG *ex; 3148d851a50bSGlenn Hammond 3149d851a50bSGlenn Hammond PetscFunctionBegin; 31509371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 3151d851a50bSGlenn Hammond pc->data = ex; 3152d851a50bSGlenn Hammond 3153d851a50bSGlenn Hammond ex->its = 1; 3154d851a50bSGlenn Hammond ex->tol = 1.e-8; 3155d851a50bSGlenn Hammond ex->relax_type = 1; 3156d851a50bSGlenn Hammond ex->num_pre_relax = 1; 3157d851a50bSGlenn Hammond ex->num_post_relax = 1; 3158d851a50bSGlenn Hammond 3159d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 3160d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 3161d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 3162d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 3163d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 3164d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 31652fa5cd67SKarl Rupp 31669566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 3167ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 3168792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 31693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3170d851a50bSGlenn Hammond } 31711c188c59Sftrigaux 3172f1580f4eSBarry Smith /* PC SMG */ 31731c188c59Sftrigaux typedef struct { 31741c188c59Sftrigaux MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 31751c188c59Sftrigaux HYPRE_StructSolver hsolver; 31761c188c59Sftrigaux PetscInt its; /* keep copy of SMG options used so may view them */ 317773dcfd97SStefano Zampini PetscReal tol; 31781c188c59Sftrigaux PetscBool print_statistics; 31791c188c59Sftrigaux PetscInt num_pre_relax, num_post_relax; 31801c188c59Sftrigaux } PC_SMG; 31811c188c59Sftrigaux 3182ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SMG(PC pc) 3183d71ae5a4SJacob Faibussowitsch { 31841c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 31851c188c59Sftrigaux 31861c188c59Sftrigaux PetscFunctionBegin; 31871c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, ex->hsolver); 31881c188c59Sftrigaux PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 31891c188c59Sftrigaux PetscCall(PetscFree(pc->data)); 31903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31911c188c59Sftrigaux } 31921c188c59Sftrigaux 3193ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SMG(PC pc, PetscViewer viewer) 3194d71ae5a4SJacob Faibussowitsch { 31951c188c59Sftrigaux PetscBool iascii; 31961c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 31971c188c59Sftrigaux 31981c188c59Sftrigaux PetscFunctionBegin; 31991c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 32001c188c59Sftrigaux if (iascii) { 32011c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SMG preconditioning\n")); 32021c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 32031c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 32041c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 32051c188c59Sftrigaux } 32063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32071c188c59Sftrigaux } 32081c188c59Sftrigaux 3209ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_SMG(PC pc, PetscOptionItems *PetscOptionsObject) 3210d71ae5a4SJacob Faibussowitsch { 32111c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 32121c188c59Sftrigaux 32131c188c59Sftrigaux PetscFunctionBegin; 32141c188c59Sftrigaux PetscOptionsHeadBegin(PetscOptionsObject, "SMG options"); 32151c188c59Sftrigaux 32161c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_its", "Number of iterations of SMG to use as preconditioner", "HYPRE_StructSMGSetMaxIter", ex->its, &ex->its, NULL)); 32171c188c59Sftrigaux 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)); 32181c188c59Sftrigaux 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)); 32191c188c59Sftrigaux PetscCall(PetscOptionsReal("-pc_smg_tol", "Tolerance of SMG", "HYPRE_StructSMGSetTol", ex->tol, &ex->tol, NULL)); 32201c188c59Sftrigaux 32211c188c59Sftrigaux PetscOptionsHeadEnd(); 32223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32231c188c59Sftrigaux } 32241c188c59Sftrigaux 3225ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SMG(PC pc, Vec x, Vec y) 3226d71ae5a4SJacob Faibussowitsch { 32271c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 32281c188c59Sftrigaux PetscScalar *yy; 32291c188c59Sftrigaux const PetscScalar *xx; 32301c188c59Sftrigaux PetscInt ilower[3], iupper[3]; 32311c188c59Sftrigaux HYPRE_Int hlower[3], hupper[3]; 3232f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 32331c188c59Sftrigaux 32341c188c59Sftrigaux PetscFunctionBegin; 32351c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 32361c188c59Sftrigaux PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 32371c188c59Sftrigaux /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 32381c188c59Sftrigaux iupper[0] += ilower[0] - 1; 32391c188c59Sftrigaux iupper[1] += ilower[1] - 1; 32401c188c59Sftrigaux iupper[2] += ilower[2] - 1; 32411c188c59Sftrigaux hlower[0] = (HYPRE_Int)ilower[0]; 32421c188c59Sftrigaux hlower[1] = (HYPRE_Int)ilower[1]; 32431c188c59Sftrigaux hlower[2] = (HYPRE_Int)ilower[2]; 32441c188c59Sftrigaux hupper[0] = (HYPRE_Int)iupper[0]; 32451c188c59Sftrigaux hupper[1] = (HYPRE_Int)iupper[1]; 32461c188c59Sftrigaux hupper[2] = (HYPRE_Int)iupper[2]; 32471c188c59Sftrigaux 32481c188c59Sftrigaux /* copy x values over to hypre */ 32491c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 32501c188c59Sftrigaux PetscCall(VecGetArrayRead(x, &xx)); 32511c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 32521c188c59Sftrigaux PetscCall(VecRestoreArrayRead(x, &xx)); 32531c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 32541c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 32551c188c59Sftrigaux 32561c188c59Sftrigaux /* copy solution values back to PETSc */ 32571c188c59Sftrigaux PetscCall(VecGetArray(y, &yy)); 32581c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 32591c188c59Sftrigaux PetscCall(VecRestoreArray(y, &yy)); 32603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32611c188c59Sftrigaux } 32621c188c59Sftrigaux 3263d71ae5a4SJacob 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) 3264d71ae5a4SJacob Faibussowitsch { 32651c188c59Sftrigaux PC_SMG *jac = (PC_SMG *)pc->data; 32661c188c59Sftrigaux HYPRE_Int oits; 32671c188c59Sftrigaux 32681c188c59Sftrigaux PetscFunctionBegin; 32691c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 32701c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, its * jac->its); 32711c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, rtol); 32721c188c59Sftrigaux 32731c188c59Sftrigaux PetscCall(PCApply_SMG(pc, b, y)); 32741c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGGetNumIterations, jac->hsolver, &oits); 32751c188c59Sftrigaux *outits = oits; 32761c188c59Sftrigaux if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 32771c188c59Sftrigaux else *reason = PCRICHARDSON_CONVERGED_RTOL; 32781c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, jac->tol); 32791c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, jac->its); 32803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32811c188c59Sftrigaux } 32821c188c59Sftrigaux 3283ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SMG(PC pc) 3284d71ae5a4SJacob Faibussowitsch { 32851c188c59Sftrigaux PetscInt i, dim; 32861c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 3287f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 32881c188c59Sftrigaux PetscBool flg; 32891c188c59Sftrigaux DMBoundaryType p[3]; 32901c188c59Sftrigaux PetscInt M[3]; 32911c188c59Sftrigaux 32921c188c59Sftrigaux PetscFunctionBegin; 32931c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 32941c188c59Sftrigaux PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 32951c188c59Sftrigaux 32961c188c59Sftrigaux PetscCall(DMDAGetInfo(mx->da, &dim, &M[0], &M[1], &M[2], 0, 0, 0, 0, 0, &p[0], &p[1], &p[2], 0)); 32971c188c59Sftrigaux // Check if power of 2 in periodic directions 32981c188c59Sftrigaux for (i = 0; i < dim; i++) { 32991c188c59Sftrigaux if (((M[i] & (M[i] - 1)) != 0) && (p[i] == DM_BOUNDARY_PERIODIC)) { 33001c188c59Sftrigaux SETERRQ(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]); 33011c188c59Sftrigaux } 33021c188c59Sftrigaux } 33031c188c59Sftrigaux 33041c188c59Sftrigaux /* create the hypre solver object and set its information */ 330557508eceSPierre Jolivet if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, ex->hsolver); 33061c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 33071c188c59Sftrigaux // The hypre options must be set here and not in SetFromOptions because it is created here! 33081c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, ex->hsolver, ex->its); 33091c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 33101c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 33111c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, ex->hsolver, ex->tol); 33121c188c59Sftrigaux 33131c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 33141c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetZeroGuess, ex->hsolver); 33153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33161c188c59Sftrigaux } 33171c188c59Sftrigaux 33181c188c59Sftrigaux /*MC 33195cb80ecdSBarry Smith PCSMG - the hypre (structured grid) SMG multigrid solver 33201c188c59Sftrigaux 33211c188c59Sftrigaux Level: advanced 33221c188c59Sftrigaux 3323f1580f4eSBarry Smith Options Database Keys: 33245cb80ecdSBarry Smith + -pc_smg_its <its> - number of iterations of SMG to use as preconditioner 33255cb80ecdSBarry Smith . -pc_smg_num_pre_relax <steps> - number of smoothing steps before coarse grid 33265cb80ecdSBarry Smith . -pc_smg_num_post_relax <steps> - number of smoothing steps after coarse grid 33275cb80ecdSBarry Smith - -pc_smg_tol <tol> - tolerance of SMG 33281c188c59Sftrigaux 33291c188c59Sftrigaux Notes: 33301c188c59Sftrigaux This is for CELL-centered descretizations 33311c188c59Sftrigaux 33325cb80ecdSBarry Smith This must be used with the `MATHYPRESTRUCT` `MatType`. 33331c188c59Sftrigaux 3334f1580f4eSBarry 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`. 3335f1580f4eSBarry Smith 3336f1580f4eSBarry Smith See `PCSYSPFMG`, `PCSMG`, `PCPFMG`, and `PCHYPRE` for access to hypre's other preconditioners 3337f1580f4eSBarry Smith 3338f1580f4eSBarry Smith .seealso: `PCMG`, `MATHYPRESTRUCT`, `PCPFMG`, `PCSYSPFMG`, `PCHYPRE`, `PCGAMG` 33391c188c59Sftrigaux M*/ 33401c188c59Sftrigaux 3341d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SMG(PC pc) 3342d71ae5a4SJacob Faibussowitsch { 33431c188c59Sftrigaux PC_SMG *ex; 33441c188c59Sftrigaux 33451c188c59Sftrigaux PetscFunctionBegin; 33469371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 33471c188c59Sftrigaux pc->data = ex; 33481c188c59Sftrigaux 33491c188c59Sftrigaux ex->its = 1; 33501c188c59Sftrigaux ex->tol = 1.e-8; 33511c188c59Sftrigaux ex->num_pre_relax = 1; 33521c188c59Sftrigaux ex->num_post_relax = 1; 33531c188c59Sftrigaux 33541c188c59Sftrigaux pc->ops->setfromoptions = PCSetFromOptions_SMG; 33551c188c59Sftrigaux pc->ops->view = PCView_SMG; 33561c188c59Sftrigaux pc->ops->destroy = PCDestroy_SMG; 33571c188c59Sftrigaux pc->ops->apply = PCApply_SMG; 33581c188c59Sftrigaux pc->ops->applyrichardson = PCApplyRichardson_SMG; 33591c188c59Sftrigaux pc->ops->setup = PCSetUp_SMG; 33601c188c59Sftrigaux 33611c188c59Sftrigaux PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 3362ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 33631c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 33643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33651c188c59Sftrigaux } 3366