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; 668131ecf7SEike Mueller PetscInt smoothnumlevels; 67ec64516dSEike Mueller PetscInt eu_level; /* Number of levels for ILU(k) in Euclid */ 6839accc25SStefano Zampini PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */ 69ec64516dSEike Mueller PetscInt eu_bj; /* Defines use of Block Jacobi ILU in Euclid */ 704ddd07fcSJed Brown PetscInt relaxtype[3]; 7139accc25SStefano Zampini PetscReal relaxweight; 7239accc25SStefano Zampini PetscReal outerrelaxweight; 734ddd07fcSJed Brown PetscInt relaxorder; 7439accc25SStefano Zampini PetscReal truncfactor; 75ace3abfcSBarry Smith PetscBool applyrichardson; 764ddd07fcSJed Brown PetscInt pmax; 774ddd07fcSJed Brown PetscInt interptype; 78589dcaf0SStefano Zampini PetscInt maxc; 79589dcaf0SStefano Zampini PetscInt minc; 80db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 81db6f9c32SMark Adams char *spgemm_type; // this is a global hypre parameter but is closely associated with BoomerAMG 82db6f9c32SMark Adams #endif 836ea7df73SStefano Zampini /* GPU */ 846ea7df73SStefano Zampini PetscBool keeptranspose; 856ea7df73SStefano Zampini PetscInt rap2; 866ea7df73SStefano Zampini PetscInt mod_rap2; 876ea7df73SStefano Zampini 88589dcaf0SStefano Zampini /* AIR */ 89589dcaf0SStefano Zampini PetscInt Rtype; 90589dcaf0SStefano Zampini PetscReal Rstrongthreshold; 91589dcaf0SStefano Zampini PetscReal Rfilterthreshold; 92589dcaf0SStefano Zampini PetscInt Adroptype; 93589dcaf0SStefano Zampini PetscReal Adroptol; 94589dcaf0SStefano Zampini 954ddd07fcSJed Brown PetscInt agg_nl; 966ea7df73SStefano Zampini PetscInt agg_interptype; 974ddd07fcSJed Brown PetscInt agg_num_paths; 98ace3abfcSBarry Smith PetscBool nodal_relax; 994ddd07fcSJed Brown PetscInt nodal_relax_levels; 1004cb006feSStefano Zampini 1015272c319SBarry Smith PetscInt nodal_coarsening; 10222e51d31SStefano Zampini PetscInt nodal_coarsening_diag; 1035272c319SBarry Smith PetscInt vec_interp_variant; 10422e51d31SStefano Zampini PetscInt vec_interp_qmax; 10522e51d31SStefano Zampini PetscBool vec_interp_smooth; 10622e51d31SStefano Zampini PetscInt interp_refine; 10722e51d31SStefano Zampini 1086ea7df73SStefano Zampini /* NearNullSpace support */ 1096ea7df73SStefano Zampini VecHYPRE_IJVector *hmnull; 1106ea7df73SStefano Zampini HYPRE_ParVector *phmnull; 1115272c319SBarry Smith PetscInt n_hmnull; 1125272c319SBarry Smith Vec hmnull_constant; 1135272c319SBarry Smith 114863406b8SStefano Zampini /* options for AS (Auxiliary Space preconditioners) */ 115863406b8SStefano Zampini PetscInt as_print; 116863406b8SStefano Zampini PetscInt as_max_iter; 117863406b8SStefano Zampini PetscReal as_tol; 118863406b8SStefano Zampini PetscInt as_relax_type; 119863406b8SStefano Zampini PetscInt as_relax_times; 120863406b8SStefano Zampini PetscReal as_relax_weight; 121863406b8SStefano Zampini PetscReal as_omega; 122863406b8SStefano 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) */ 123863406b8SStefano Zampini PetscReal as_amg_alpha_theta; /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */ 124863406b8SStefano 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) */ 125863406b8SStefano Zampini PetscReal as_amg_beta_theta; /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS) */ 1264cb006feSStefano Zampini PetscInt ams_cycle_type; 127863406b8SStefano Zampini PetscInt ads_cycle_type; 1284cb006feSStefano Zampini 1294cb006feSStefano Zampini /* additional data */ 1305ac14e1cSStefano Zampini Mat G; /* MatHYPRE */ 1315ac14e1cSStefano Zampini Mat C; /* MatHYPRE */ 1325ac14e1cSStefano Zampini Mat alpha_Poisson; /* MatHYPRE */ 1335ac14e1cSStefano Zampini Mat beta_Poisson; /* MatHYPRE */ 1345ac14e1cSStefano Zampini 1355ac14e1cSStefano Zampini /* extra information for AMS */ 1365ac14e1cSStefano Zampini PetscInt dim; /* geometrical dimension */ 1376ea7df73SStefano Zampini VecHYPRE_IJVector coords[3]; 1386ea7df73SStefano Zampini VecHYPRE_IJVector constants[3]; 139be14dc20SKerry Key VecHYPRE_IJVector interior; 1406bf688a0SCe Qin Mat RT_PiFull, RT_Pi[3]; 1416bf688a0SCe Qin Mat ND_PiFull, ND_Pi[3]; 1424cb006feSStefano Zampini PetscBool ams_beta_is_zero; 14323df4f25SStefano Zampini PetscBool ams_beta_is_zero_part; 14423df4f25SStefano Zampini PetscInt ams_proj_freq; 14516d9e3a6SLisandro Dalcin } PC_HYPRE; 14616d9e3a6SLisandro Dalcin 147fd2dd295SFande Kong /* 1488a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1498a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1508a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 151fd2dd295SFande Kong */ 152d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc, PetscInt *nlevels, Mat *operators[]) 153d71ae5a4SJacob Faibussowitsch { 1548a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1558a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1568a2c336bSFande Kong PetscInt num_levels, l; 1578a2c336bSFande Kong Mat *mattmp; 1588a2c336bSFande Kong hypre_ParCSRMatrix **A_array; 1598a2c336bSFande Kong 1608a2c336bSFande Kong PetscFunctionBegin; 1619566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same)); 1625f80ce2aSJacob Faibussowitsch PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG "); 1638a2c336bSFande Kong num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)(jac->hsolver)); 1649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels, &mattmp)); 1658a2c336bSFande Kong A_array = hypre_ParAMGDataAArray((hypre_ParAMGData *)(jac->hsolver)); 1668a2c336bSFande Kong for (l = 1; l < num_levels; l++) { 1679566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(A_array[l], MATAIJ, PETSC_OWN_POINTER, &(mattmp[num_levels - 1 - l]))); 1688a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 1698a2c336bSFande Kong A_array[l] = NULL; 1708a2c336bSFande Kong } 1718a2c336bSFande Kong *nlevels = num_levels; 1728a2c336bSFande Kong *operators = mattmp; 1733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1748a2c336bSFande Kong } 1758a2c336bSFande Kong 176fd2dd295SFande Kong /* 1778a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1788a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1798a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 180fd2dd295SFande Kong */ 181d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc, PetscInt *nlevels, Mat *interpolations[]) 182d71ae5a4SJacob Faibussowitsch { 1838a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1848a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1858a2c336bSFande Kong PetscInt num_levels, l; 1868a2c336bSFande Kong Mat *mattmp; 1878a2c336bSFande Kong hypre_ParCSRMatrix **P_array; 1888a2c336bSFande Kong 1898a2c336bSFande Kong PetscFunctionBegin; 1909566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same)); 1915f80ce2aSJacob Faibussowitsch PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG "); 1928a2c336bSFande Kong num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)(jac->hsolver)); 1939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels, &mattmp)); 1948a2c336bSFande Kong P_array = hypre_ParAMGDataPArray((hypre_ParAMGData *)(jac->hsolver)); 1958a2c336bSFande Kong for (l = 1; l < num_levels; l++) { 1969566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(P_array[num_levels - 1 - l], MATAIJ, PETSC_OWN_POINTER, &(mattmp[l - 1]))); 1978a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 1988a2c336bSFande Kong P_array[num_levels - 1 - l] = NULL; 1998a2c336bSFande Kong } 2008a2c336bSFande Kong *nlevels = num_levels; 2018a2c336bSFande Kong *interpolations = mattmp; 2023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2038a2c336bSFande Kong } 2048a2c336bSFande Kong 205ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */ 206d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc) 207d71ae5a4SJacob Faibussowitsch { 208ce6a8a0dSJed Brown PC_HYPRE *jac = (PC_HYPRE *)pc->data; 209ce6a8a0dSJed Brown PetscInt i; 210ce6a8a0dSJed Brown 2119d678128SJed Brown PetscFunctionBegin; 21248a46eb9SPierre Jolivet for (i = 0; i < jac->n_hmnull; i++) PetscCall(VecHYPRE_IJVectorDestroy(&jac->hmnull[i])); 2139566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hmnull)); 2149566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->phmnull)); 2159566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->hmnull_constant)); 2169d678128SJed Brown jac->n_hmnull = 0; 2173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 218ce6a8a0dSJed Brown } 219ce6a8a0dSJed Brown 220d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_HYPRE(PC pc) 221d71ae5a4SJacob Faibussowitsch { 22216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 22349a781f5SStefano Zampini Mat_HYPRE *hjac; 22416d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 22516d9e3a6SLisandro Dalcin HYPRE_ParVector bv, xv; 22649a781f5SStefano Zampini PetscBool ishypre; 22716d9e3a6SLisandro Dalcin 22816d9e3a6SLisandro Dalcin PetscFunctionBegin; 2290df1829cSStefano Zampini /* default type is boomerAMG */ 23048a46eb9SPierre Jolivet if (!jac->hypre_type) PetscCall(PCHYPRESetType(pc, "boomeramg")); 2315f5c5b43SBarry Smith 2320df1829cSStefano Zampini /* get hypre matrix */ 2330df1829cSStefano Zampini if (pc->flag == DIFFERENT_NONZERO_PATTERN) PetscCall(MatDestroy(&jac->hpmat)); 2349566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRE, &ishypre)); 23549a781f5SStefano Zampini if (!ishypre) { 2360df1829cSStefano Zampini /* Temporary fix since we do not support MAT_REUSE_MATRIX with HYPRE device */ 2370df1829cSStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 2380df1829cSStefano Zampini PetscBool iscuda, iship, iskokkos; 2390df1829cSStefano Zampini 2400df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iscuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, "")); 2410df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iship, MATSEQAIJHIPSPARSE, MATMPIAIJHIPSPARSE, "")); 2420df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iskokkos, MATSEQAIJKOKKOS, MATMPIAIJKOKKOS, "")); 2430df1829cSStefano Zampini if (iscuda || iship || iskokkos) PetscCall(MatDestroy(&jac->hpmat)); 2440df1829cSStefano Zampini #endif 2450df1829cSStefano Zampini PetscCall(MatConvert(pc->pmat, MATHYPRE, jac->hpmat ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX, &jac->hpmat)); 24649a781f5SStefano Zampini } else { 2479566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc->pmat)); 2489566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 24949a781f5SStefano Zampini jac->hpmat = pc->pmat; 25016d9e3a6SLisandro Dalcin } 2510df1829cSStefano Zampini 2526ea7df73SStefano Zampini /* allow debug */ 2539566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(jac->hpmat, NULL, "-pc_hypre_mat_view")); 25449a781f5SStefano Zampini hjac = (Mat_HYPRE *)(jac->hpmat->data); 2555f5c5b43SBarry Smith 25616d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 25716d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 2585272c319SBarry Smith MatNullSpace mnull; 2595272c319SBarry Smith PetscBool has_const; 26049a781f5SStefano Zampini PetscInt bs, nvec, i; 2615272c319SBarry Smith const Vec *vecs; 2625272c319SBarry Smith 2639566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat, &bs)); 264792fecdfSBarry Smith if (bs > 1) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 2659566063dSJacob Faibussowitsch PetscCall(MatGetNearNullSpace(pc->mat, &mnull)); 2665272c319SBarry Smith if (mnull) { 2679566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 2689566063dSJacob Faibussowitsch PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs)); 2699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->hmnull)); 2709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->phmnull)); 2715272c319SBarry Smith for (i = 0; i < nvec; i++) { 2729566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map, &jac->hmnull[i])); 2739566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(vecs[i], jac->hmnull[i])); 274792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[i]->ij, (void **)&jac->phmnull[i]); 2755272c319SBarry Smith } 2765272c319SBarry Smith if (has_const) { 2779566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(pc->pmat, &jac->hmnull_constant, NULL)); 2789566063dSJacob Faibussowitsch PetscCall(VecSet(jac->hmnull_constant, 1)); 2799566063dSJacob Faibussowitsch PetscCall(VecNormalize(jac->hmnull_constant, NULL)); 2809566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map, &jac->hmnull[nvec])); 2819566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant, jac->hmnull[nvec])); 282792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[nvec]->ij, (void **)&jac->phmnull[nvec]); 2835272c319SBarry Smith nvec++; 2845272c319SBarry Smith } 285792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVectors, jac->hsolver, nvec, jac->phmnull); 2865272c319SBarry Smith jac->n_hmnull = nvec; 2875272c319SBarry Smith } 2884cb006feSStefano Zampini } 289863406b8SStefano Zampini 2904cb006feSStefano Zampini /* special case for AMS */ 2914cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 2925ac14e1cSStefano Zampini Mat_HYPRE *hm; 2935ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 2946bf688a0SCe Qin if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 295f1580f4eSBarry 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()"); 2966bf688a0SCe Qin } 29748a46eb9SPierre Jolivet if (jac->dim) PetscCallExternal(HYPRE_AMSSetDimension, jac->hsolver, jac->dim); 2985ac14e1cSStefano Zampini if (jac->constants[0]) { 2995ac14e1cSStefano Zampini HYPRE_ParVector ozz, zoz, zzo = NULL; 300792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[0]->ij, (void **)(&ozz)); 301792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[1]->ij, (void **)(&zoz)); 30248a46eb9SPierre Jolivet if (jac->constants[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[2]->ij, (void **)(&zzo)); 303792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetEdgeConstantVectors, jac->hsolver, ozz, zoz, zzo); 3045ac14e1cSStefano Zampini } 3055ac14e1cSStefano Zampini if (jac->coords[0]) { 3065ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3075ac14e1cSStefano Zampini coords[0] = NULL; 3085ac14e1cSStefano Zampini coords[1] = NULL; 3095ac14e1cSStefano Zampini coords[2] = NULL; 310792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 311792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 312792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 313792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 3145ac14e1cSStefano Zampini } 3155f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3165ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->G->data); 317792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 318792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDiscreteGradient, jac->hsolver, parcsr); 3195ac14e1cSStefano Zampini if (jac->alpha_Poisson) { 3205ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->alpha_Poisson->data); 321792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 322792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaPoissonMatrix, jac->hsolver, parcsr); 3235ac14e1cSStefano Zampini } 3245ac14e1cSStefano Zampini if (jac->ams_beta_is_zero) { 325792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, NULL); 3265ac14e1cSStefano Zampini } else if (jac->beta_Poisson) { 3275ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->beta_Poisson->data); 328792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 329792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, parcsr); 330be14dc20SKerry Key } else if (jac->ams_beta_is_zero_part) { 331be14dc20SKerry Key if (jac->interior) { 332be14dc20SKerry Key HYPRE_ParVector interior = NULL; 333be14dc20SKerry Key PetscCallExternal(HYPRE_IJVectorGetObject, jac->interior->ij, (void **)(&interior)); 334be14dc20SKerry Key PetscCallExternal(HYPRE_AMSSetInteriorNodes, jac->hsolver, interior); 335be14dc20SKerry Key } else { 336be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 337be14dc20SKerry Key } 3385ac14e1cSStefano Zampini } 3396bf688a0SCe Qin if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) { 3406bf688a0SCe Qin PetscInt i; 3416bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3426bf688a0SCe Qin if (jac->ND_PiFull) { 3436bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->ND_PiFull->data); 344792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 3456bf688a0SCe Qin } else { 3466bf688a0SCe Qin nd_parcsrfull = NULL; 3476bf688a0SCe Qin } 3486bf688a0SCe Qin for (i = 0; i < 3; ++i) { 3496bf688a0SCe Qin if (jac->ND_Pi[i]) { 3506bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->ND_Pi[i]->data); 351792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 3526bf688a0SCe Qin } else { 3536bf688a0SCe Qin nd_parcsr[i] = NULL; 3546bf688a0SCe Qin } 3556bf688a0SCe Qin } 356792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetInterpolations, jac->hsolver, nd_parcsrfull, nd_parcsr[0], nd_parcsr[1], nd_parcsr[2]); 3576bf688a0SCe Qin } 3584cb006feSStefano Zampini } 359863406b8SStefano Zampini /* special case for ADS */ 360863406b8SStefano Zampini if (jac->setup == HYPRE_ADSSetup) { 3615ac14e1cSStefano Zampini Mat_HYPRE *hm; 3625ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 3636bf688a0SCe 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])))) { 3646bf688a0SCe Qin SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations"); 3659371c9d4SSatish 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"); 3665f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3675f80ce2aSJacob Faibussowitsch PetscCheck(jac->C, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient"); 3685ac14e1cSStefano Zampini if (jac->coords[0]) { 3695ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3705ac14e1cSStefano Zampini coords[0] = NULL; 3715ac14e1cSStefano Zampini coords[1] = NULL; 3725ac14e1cSStefano Zampini coords[2] = NULL; 373792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 374792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 375792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 376792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 3775ac14e1cSStefano Zampini } 3785ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->G->data); 379792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 380792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteGradient, jac->hsolver, parcsr); 3815ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->C->data); 382792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 383792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteCurl, jac->hsolver, parcsr); 3846bf688a0SCe Qin if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 3856bf688a0SCe Qin PetscInt i; 3866bf688a0SCe Qin HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3]; 3876bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3886bf688a0SCe Qin if (jac->RT_PiFull) { 3896bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->RT_PiFull->data); 390792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsrfull)); 3916bf688a0SCe Qin } else { 3926bf688a0SCe Qin rt_parcsrfull = NULL; 3936bf688a0SCe Qin } 3946bf688a0SCe Qin for (i = 0; i < 3; ++i) { 3956bf688a0SCe Qin if (jac->RT_Pi[i]) { 3966bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->RT_Pi[i]->data); 397792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsr[i])); 3986bf688a0SCe Qin } else { 3996bf688a0SCe Qin rt_parcsr[i] = NULL; 4006bf688a0SCe Qin } 4016bf688a0SCe Qin } 4026bf688a0SCe Qin if (jac->ND_PiFull) { 4036bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->ND_PiFull->data); 404792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 4056bf688a0SCe Qin } else { 4066bf688a0SCe Qin nd_parcsrfull = NULL; 4076bf688a0SCe Qin } 4086bf688a0SCe Qin for (i = 0; i < 3; ++i) { 4096bf688a0SCe Qin if (jac->ND_Pi[i]) { 4106bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->ND_Pi[i]->data); 411792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 4126bf688a0SCe Qin } else { 4136bf688a0SCe Qin nd_parcsr[i] = NULL; 4146bf688a0SCe Qin } 4156bf688a0SCe Qin } 416792fecdfSBarry 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]); 4176bf688a0SCe Qin } 418863406b8SStefano Zampini } 419792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 420792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&bv); 421792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&xv); 42297c1e3cbSStefano Zampini PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 423792fecdfSBarry Smith PetscCallExternal(jac->setup, jac->hsolver, hmat, bv, xv); 42497c1e3cbSStefano Zampini PetscCall(PetscFPTrapPop()); 4253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42616d9e3a6SLisandro Dalcin } 42716d9e3a6SLisandro Dalcin 428d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_HYPRE(PC pc, Vec b, Vec x) 429d71ae5a4SJacob Faibussowitsch { 43016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 43149a781f5SStefano Zampini Mat_HYPRE *hjac = (Mat_HYPRE *)(jac->hpmat->data); 43216d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 43316d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 43416d9e3a6SLisandro Dalcin 43516d9e3a6SLisandro Dalcin PetscFunctionBegin; 4369566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 4379566063dSJacob Faibussowitsch if (!jac->applyrichardson) PetscCall(VecSet(x, 0.0)); 4389566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b, b)); 4399566063dSJacob Faibussowitsch if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x, x)); 4409566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x, x)); 441792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 442792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 443792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 4449371c9d4SSatish Balay PetscStackCallExternalVoid( 4459371c9d4SSatish Balay "Hypre solve", do { 4465f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = (*jac->solve)(jac->hsolver, hmat, jbv, jxv); 4475f80ce2aSJacob Faibussowitsch if (hierr) { 4485f80ce2aSJacob Faibussowitsch PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 44985245615SPierre Jolivet HYPRE_ClearAllErrors(); 4505f80ce2aSJacob Faibussowitsch } 4515f80ce2aSJacob Faibussowitsch } while (0)); 45216d9e3a6SLisandro Dalcin 45348a46eb9SPierre Jolivet if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) PetscCallExternal(HYPRE_AMSProjectOutGradients, jac->hsolver, jxv); 4549566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 4559566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 4563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45716d9e3a6SLisandro Dalcin } 45816d9e3a6SLisandro Dalcin 45985245615SPierre Jolivet static PetscErrorCode PCMatApply_HYPRE_BoomerAMG(PC pc, Mat B, Mat X) 46085245615SPierre Jolivet { 46185245615SPierre Jolivet PC_HYPRE *jac = (PC_HYPRE *)pc->data; 46285245615SPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)(jac->hpmat->data); 46385245615SPierre Jolivet hypre_ParCSRMatrix *par_matrix; 46485245615SPierre Jolivet HYPRE_ParVector hb, hx; 46585245615SPierre Jolivet const PetscScalar *b; 46685245615SPierre Jolivet PetscScalar *x; 46785245615SPierre Jolivet PetscInt m, N, lda; 46885245615SPierre Jolivet hypre_Vector *x_local; 46985245615SPierre Jolivet PetscMemType type; 47085245615SPierre Jolivet 47185245615SPierre Jolivet PetscFunctionBegin; 47285245615SPierre Jolivet PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 47385245615SPierre Jolivet PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&par_matrix); 47485245615SPierre Jolivet PetscCall(MatGetLocalSize(B, &m, NULL)); 47585245615SPierre Jolivet PetscCall(MatGetSize(B, NULL, &N)); 47685245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hb); 47785245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hx); 47885245615SPierre Jolivet PetscCall(MatZeroEntries(X)); 47985245615SPierre Jolivet PetscCall(MatDenseGetArrayReadAndMemType(B, &b, &type)); 48085245615SPierre Jolivet PetscCall(MatDenseGetLDA(B, &lda)); 48185245615SPierre 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); 48285245615SPierre Jolivet PetscCall(MatDenseGetLDA(X, &lda)); 48385245615SPierre 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); 48485245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hb); 48585245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 48685245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)b; 48785245615SPierre Jolivet PetscCall(MatDenseGetArrayWriteAndMemType(X, &x, NULL)); 48885245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hx); 48985245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 49085245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)x; 49185245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hb, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 49285245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hx, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 49385245615SPierre Jolivet PetscStackCallExternalVoid( 49485245615SPierre Jolivet "Hypre solve", do { 49585245615SPierre Jolivet HYPRE_Int hierr = (*jac->solve)(jac->hsolver, par_matrix, hb, hx); 49685245615SPierre Jolivet if (hierr) { 49785245615SPierre Jolivet PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 49885245615SPierre Jolivet HYPRE_ClearAllErrors(); 49985245615SPierre Jolivet } 50085245615SPierre Jolivet } while (0)); 50185245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hb); 50285245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hx); 50385245615SPierre Jolivet PetscCall(MatDenseRestoreArrayReadAndMemType(B, &b)); 50485245615SPierre Jolivet PetscCall(MatDenseRestoreArrayWriteAndMemType(X, &x)); 50585245615SPierre Jolivet PetscFunctionReturn(PETSC_SUCCESS); 50685245615SPierre Jolivet } 50785245615SPierre Jolivet 508d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_HYPRE(PC pc) 509d71ae5a4SJacob Faibussowitsch { 5108695de01SBarry Smith PC_HYPRE *jac = (PC_HYPRE *)pc->data; 5118695de01SBarry Smith 5128695de01SBarry Smith PetscFunctionBegin; 5139566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 5149566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 5159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 5169566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 5179566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 5189566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 5199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[0])); 5209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[1])); 5219566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[2])); 5229566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 5239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[0])); 5249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[1])); 5259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[2])); 5269566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 5279566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 5289566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 5299566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 5309566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 5319566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 532be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 5339566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 5345ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 535be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 5365ac14e1cSStefano Zampini jac->dim = 0; 5373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5388695de01SBarry Smith } 5398695de01SBarry Smith 540d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_HYPRE(PC pc) 541d71ae5a4SJacob Faibussowitsch { 54216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 54316d9e3a6SLisandro Dalcin 54416d9e3a6SLisandro Dalcin PetscFunctionBegin; 5459566063dSJacob Faibussowitsch PetscCall(PCReset_HYPRE(pc)); 546792fecdfSBarry Smith if (jac->destroy) PetscCallExternal(jac->destroy, jac->hsolver); 5479566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 548db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 5499566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->spgemm_type)); 550db6f9c32SMark Adams #endif 5519566063dSJacob Faibussowitsch if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 5529566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 55316d9e3a6SLisandro Dalcin 5549566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc, 0)); 5559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", NULL)); 5569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", NULL)); 5579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", NULL)); 5589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", NULL)); 5599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", NULL)); 5609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetConstantEdgeVectors_C", NULL)); 5619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", NULL)); 5622e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", NULL)); 563be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", NULL)); 5649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", NULL)); 5659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", NULL)); 5669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", NULL)); 5679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", NULL)); 5682e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", NULL)); 5693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57016d9e3a6SLisandro Dalcin } 57116d9e3a6SLisandro Dalcin 572d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc, PetscOptionItems *PetscOptionsObject) 573d71ae5a4SJacob Faibussowitsch { 57416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 575ace3abfcSBarry Smith PetscBool flag; 57616d9e3a6SLisandro Dalcin 57716d9e3a6SLisandro Dalcin PetscFunctionBegin; 578d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Pilut Options"); 5799566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter", "Number of iterations", "None", jac->maxiter, &jac->maxiter, &flag)); 580792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetMaxIter, jac->hsolver, jac->maxiter); 5819566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol", "Drop tolerance", "None", jac->tol, &jac->tol, &flag)); 582792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetDropTolerance, jac->hsolver, jac->tol); 5839566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize", "FactorRowSize", "None", jac->factorrowsize, &jac->factorrowsize, &flag)); 584792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetFactorRowSize, jac->hsolver, jac->factorrowsize); 585d0609cedSBarry Smith PetscOptionsHeadEnd(); 5863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58716d9e3a6SLisandro Dalcin } 58816d9e3a6SLisandro Dalcin 589d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Pilut(PC pc, PetscViewer viewer) 590d71ae5a4SJacob Faibussowitsch { 59116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 592ace3abfcSBarry Smith PetscBool iascii; 59316d9e3a6SLisandro Dalcin 59416d9e3a6SLisandro Dalcin PetscFunctionBegin; 5959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 59616d9e3a6SLisandro Dalcin if (iascii) { 5979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Pilut preconditioning\n")); 59816d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 59963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum number of iterations %" PetscInt_FMT "\n", jac->maxiter)); 60016d9e3a6SLisandro Dalcin } else { 6019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default maximum number of iterations \n")); 60216d9e3a6SLisandro Dalcin } 60316d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 6049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->tol)); 60516d9e3a6SLisandro Dalcin } else { 6069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default drop tolerance \n")); 60716d9e3a6SLisandro Dalcin } 60816d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 60963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factor row size %" PetscInt_FMT "\n", jac->factorrowsize)); 61016d9e3a6SLisandro Dalcin } else { 6119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factor row size \n")); 61216d9e3a6SLisandro Dalcin } 61316d9e3a6SLisandro Dalcin } 6143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 61516d9e3a6SLisandro Dalcin } 61616d9e3a6SLisandro Dalcin 617d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc, PetscOptionItems *PetscOptionsObject) 618d71ae5a4SJacob Faibussowitsch { 619db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 6208bf83915SBarry Smith PetscBool flag, eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE; 621db966c6cSHong Zhang 622db966c6cSHong Zhang PetscFunctionBegin; 623d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Euclid Options"); 6249566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_euclid_level", "Factorization levels", "None", jac->eu_level, &jac->eu_level, &flag)); 625792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_EuclidSetLevel, jac->hsolver, jac->eu_level); 6268bf83915SBarry Smith 6279566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_euclid_droptolerance", "Drop tolerance for ILU(k) in Euclid", "None", jac->eu_droptolerance, &jac->eu_droptolerance, &flag)); 6288bf83915SBarry Smith if (flag) { 6298bf83915SBarry Smith PetscMPIInt size; 6308bf83915SBarry Smith 6319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc), &size)); 6327827d75bSBarry Smith PetscCheck(size == 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "hypre's Euclid does not support a parallel drop tolerance"); 633792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetILUT, jac->hsolver, jac->eu_droptolerance); 6348bf83915SBarry Smith } 6358bf83915SBarry Smith 6369566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj, &eu_bj, &flag)); 6378bf83915SBarry Smith if (flag) { 6388bf83915SBarry Smith jac->eu_bj = eu_bj ? 1 : 0; 639792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetBJ, jac->hsolver, jac->eu_bj); 6408bf83915SBarry Smith } 641d0609cedSBarry Smith PetscOptionsHeadEnd(); 6423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 643db966c6cSHong Zhang } 644db966c6cSHong Zhang 645d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Euclid(PC pc, PetscViewer viewer) 646d71ae5a4SJacob Faibussowitsch { 647db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 648db966c6cSHong Zhang PetscBool iascii; 649db966c6cSHong Zhang 650db966c6cSHong Zhang PetscFunctionBegin; 6519566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 652db966c6cSHong Zhang if (iascii) { 6539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Euclid preconditioning\n")); 654db966c6cSHong Zhang if (jac->eu_level != PETSC_DEFAULT) { 65563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factorization levels %" PetscInt_FMT "\n", jac->eu_level)); 656db966c6cSHong Zhang } else { 6579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factorization levels \n")); 658db966c6cSHong Zhang } 6599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->eu_droptolerance)); 66063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 661db966c6cSHong Zhang } 6623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 663db966c6cSHong Zhang } 664db966c6cSHong Zhang 665d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc, Vec b, Vec x) 666d71ae5a4SJacob Faibussowitsch { 66716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 66849a781f5SStefano Zampini Mat_HYPRE *hjac = (Mat_HYPRE *)(jac->hpmat->data); 66916d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 67016d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 67116d9e3a6SLisandro Dalcin 67216d9e3a6SLisandro Dalcin PetscFunctionBegin; 6739566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 6749566063dSJacob Faibussowitsch PetscCall(VecSet(x, 0.0)); 6759566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->x, b)); 6769566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->b, x)); 67716d9e3a6SLisandro Dalcin 678792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 679792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 680792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 68116d9e3a6SLisandro Dalcin 6829371c9d4SSatish Balay PetscStackCallExternalVoid( 6839371c9d4SSatish Balay "Hypre Transpose solve", do { 6845f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver, hmat, jbv, jxv); 6855f80ce2aSJacob Faibussowitsch if (hierr) { 68616d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 6875f80ce2aSJacob Faibussowitsch PetscCheck(hierr == 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 68885245615SPierre Jolivet HYPRE_ClearAllErrors(); 6895f80ce2aSJacob Faibussowitsch } 6905f80ce2aSJacob Faibussowitsch } while (0)); 69116d9e3a6SLisandro Dalcin 6929566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 6939566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 6943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 69516d9e3a6SLisandro Dalcin } 69616d9e3a6SLisandro Dalcin 697d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char name[]) 698d71ae5a4SJacob Faibussowitsch { 699db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 700db6f9c32SMark Adams PetscBool flag; 701db6f9c32SMark Adams 702db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 703db6f9c32SMark Adams PetscFunctionBegin; 704db6f9c32SMark Adams if (jac->spgemm_type) { 7059566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->spgemm_type, name, &flag)); 70628b400f6SJacob Faibussowitsch PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "Cannot reset the HYPRE SpGEMM (really we can)"); 7073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 708db6f9c32SMark Adams } else { 7099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->spgemm_type)); 710db6f9c32SMark Adams } 7119566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("cusparse", jac->spgemm_type, &flag)); 712db6f9c32SMark Adams if (flag) { 713792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 1); 7143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 715db6f9c32SMark Adams } 7169566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("hypre", jac->spgemm_type, &flag)); 717db6f9c32SMark Adams if (flag) { 718792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 0); 7193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 720db6f9c32SMark Adams } 721db6f9c32SMark Adams jac->spgemm_type = NULL; 7222d6c3ceeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE SpGEMM type %s; Choices are cusparse, hypre", name); 723db6f9c32SMark Adams #endif 724db6f9c32SMark Adams } 725db6f9c32SMark Adams 726d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[]) 727d71ae5a4SJacob Faibussowitsch { 728db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 729db6f9c32SMark Adams 730db6f9c32SMark Adams PetscFunctionBegin; 731db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 732db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 733db6f9c32SMark Adams *spgemm = jac->spgemm_type; 734db6f9c32SMark Adams #endif 7353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 736db6f9c32SMark Adams } 737db6f9c32SMark Adams 73816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"", "V", "W"}; 7390f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP", "Ruge-Stueben", "", "modifiedRuge-Stueben", "", "", "Falgout", "", "PMIS", "", "HMIS"}; 74016d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local", "global"}; 74165de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 7426a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[] = {"Schwarz-smoothers", "Pilut", "ParaSails", "Euclid"}; 7439371c9d4SSatish 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"}; 7449371c9d4SSatish 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"}; 745d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc, PetscOptionItems *PetscOptionsObject) 746d71ae5a4SJacob Faibussowitsch { 74716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 74822e51d31SStefano Zampini PetscInt bs, n, indx, level; 749ace3abfcSBarry Smith PetscBool flg, tmp_truth; 75016d9e3a6SLisandro Dalcin double tmpdbl, twodbl[2]; 751589dcaf0SStefano Zampini const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 752db6f9c32SMark Adams const char *PCHYPRESpgemmTypes[] = {"cusparse", "hypre"}; 75316d9e3a6SLisandro Dalcin 75416d9e3a6SLisandro Dalcin PetscFunctionBegin; 755d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE BoomerAMG Options"); 7569566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type", "Cycle type", "None", HYPREBoomerAMGCycleType + 1, 2, HYPREBoomerAMGCycleType[jac->cycletype], &indx, &flg)); 75716d9e3a6SLisandro Dalcin if (flg) { 7584336a9eeSBarry Smith jac->cycletype = indx + 1; 759792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 76016d9e3a6SLisandro Dalcin } 761*52ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_levels", "Number of levels (of grids) allowed", "None", jac->maxlevels, &jac->maxlevels, &flg, 2)); 762*52ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 763*52ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_iter", "Maximum iterations used PER hypre call", "None", jac->maxiter, &jac->maxiter, &flg, 1)); 764*52ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 765*52ce0ab5SPierre 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)); 766*52ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 76722e51d31SStefano Zampini bs = 1; 76848a46eb9SPierre Jolivet if (pc->pmat) PetscCall(MatGetBlockSize(pc->pmat, &bs)); 7699566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions", "Number of functions", "HYPRE_BoomerAMGSetNumFunctions", bs, &bs, &flg)); 77048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 77116d9e3a6SLisandro Dalcin 772*52ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_truncfactor", "Truncation factor for interpolation (0=no truncation)", "None", jac->truncfactor, &jac->truncfactor, &flg, 0.0)); 773*52ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 77416d9e3a6SLisandro Dalcin 775*52ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_P_max", "Max elements per row for interpolation operator (0=unlimited)", "None", jac->pmax, &jac->pmax, &flg, 0)); 776*52ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 7770f1074feSSatish Balay 7789566063dSJacob 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)); 779792fecdfSBarry Smith if (flg) PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 7800f1074feSSatish Balay 781*52ce0ab5SPierre 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)); 782*52ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 7830f1074feSSatish Balay 784*52ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_strong_threshold", "Threshold for being strongly connected", "None", jac->strongthreshold, &jac->strongthreshold, &flg, 0.0)); 785*52ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 786*52ce0ab5SPierre Jolivet PetscCall(PetscOptionsRangeReal("-pc_hypre_boomeramg_max_row_sum", "Maximum row sum", "None", jac->maxrowsum, &jac->maxrowsum, &flg, 0.0, 1.0)); 787*52ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 78816d9e3a6SLisandro Dalcin 78916d9e3a6SLisandro Dalcin /* Grid sweeps */ 7909566063dSJacob 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)); 79116d9e3a6SLisandro Dalcin if (flg) { 792792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps, jac->hsolver, indx); 79316d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 79416d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 7950f1074feSSatish Balay jac->gridsweeps[1] = indx; 7960f1074feSSatish Balay /*defaults coarse to 1 */ 7970f1074feSSatish Balay jac->gridsweeps[2] = 1; 79816d9e3a6SLisandro Dalcin } 7999566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen", "Use a nodal based coarsening 1-6", "HYPRE_BoomerAMGSetNodal", jac->nodal_coarsening, &jac->nodal_coarsening, &flg)); 80048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodal, jac->hsolver, jac->nodal_coarsening); 8019566063dSJacob 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)); 80248a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodalDiag, jac->hsolver, jac->nodal_coarsening_diag); 8039566063dSJacob 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)); 80448a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecVariant, jac->hsolver, jac->vec_interp_variant); 8059566063dSJacob 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)); 80648a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecQMax, jac->hsolver, jac->vec_interp_qmax); 8079566063dSJacob 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)); 80848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetSmoothInterpVectors, jac->hsolver, jac->vec_interp_smooth); 8099566063dSJacob 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)); 81048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpRefine, jac->hsolver, jac->interp_refine); 8119566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down", "Number of sweeps for the down cycles", "None", jac->gridsweeps[0], &indx, &flg)); 81216d9e3a6SLisandro Dalcin if (flg) { 813792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 1); 8140f1074feSSatish Balay jac->gridsweeps[0] = indx; 81516d9e3a6SLisandro Dalcin } 8169566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up", "Number of sweeps for the up cycles", "None", jac->gridsweeps[1], &indx, &flg)); 81716d9e3a6SLisandro Dalcin if (flg) { 818792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 2); 8190f1074feSSatish Balay jac->gridsweeps[1] = indx; 82016d9e3a6SLisandro Dalcin } 8219566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse", "Number of sweeps for the coarse level", "None", jac->gridsweeps[2], &indx, &flg)); 82216d9e3a6SLisandro Dalcin if (flg) { 823792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 3); 8240f1074feSSatish Balay jac->gridsweeps[2] = indx; 82516d9e3a6SLisandro Dalcin } 82616d9e3a6SLisandro Dalcin 8276a251517SEike Mueller /* Smooth type */ 828dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type", "Enable more complex smoothers", "None", HYPREBoomerAMGSmoothType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType), HYPREBoomerAMGSmoothType[0], &indx, &flg)); 8296a251517SEike Mueller if (flg) { 8306a251517SEike Mueller jac->smoothtype = indx; 831792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, indx + 6); 8328131ecf7SEike Mueller jac->smoothnumlevels = 25; 833792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, 25); 8348131ecf7SEike Mueller } 8358131ecf7SEike Mueller 8368131ecf7SEike Mueller /* Number of smoothing levels */ 8379566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels", "Number of levels on which more complex smoothers are used", "None", 25, &indx, &flg)); 8388131ecf7SEike Mueller if (flg && (jac->smoothtype != -1)) { 8398131ecf7SEike Mueller jac->smoothnumlevels = indx; 840792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, indx); 8416a251517SEike Mueller } 8426a251517SEike Mueller 8431810e44eSEike Mueller /* Number of levels for ILU(k) for Euclid */ 8449566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level", "Number of levels for ILU(k) in Euclid smoother", "None", 0, &indx, &flg)); 8451810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8461810e44eSEike Mueller jac->eu_level = indx; 847792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, indx); 8481810e44eSEike Mueller } 8491810e44eSEike Mueller 8501810e44eSEike Mueller /* Filter for ILU(k) for Euclid */ 8511810e44eSEike Mueller double droptolerance; 8529566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance", "Drop tolerance for ILU(k) in Euclid smoother", "None", 0, &droptolerance, &flg)); 8531810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8541810e44eSEike Mueller jac->eu_droptolerance = droptolerance; 855792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, droptolerance); 8561810e44eSEike Mueller } 8571810e44eSEike Mueller 8581810e44eSEike Mueller /* Use Block Jacobi ILUT for Euclid */ 8599566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg)); 8601810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8611810e44eSEike Mueller jac->eu_bj = tmp_truth; 862792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuBJ, jac->hsolver, jac->eu_bj); 8631810e44eSEike Mueller } 8641810e44eSEike Mueller 86516d9e3a6SLisandro Dalcin /* Relax type */ 866dd39110bSPierre 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)); 86716d9e3a6SLisandro Dalcin if (flg) { 8680f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 869792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, indx); 8700f1074feSSatish Balay /* by default, coarse type set to 9 */ 8710f1074feSSatish Balay jac->relaxtype[2] = 9; 872792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, 9, 3); 87316d9e3a6SLisandro Dalcin } 874dd39110bSPierre 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)); 87516d9e3a6SLisandro Dalcin if (flg) { 87616d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 877792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 1); 87816d9e3a6SLisandro Dalcin } 879dd39110bSPierre 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)); 88016d9e3a6SLisandro Dalcin if (flg) { 8810f1074feSSatish Balay jac->relaxtype[1] = indx; 882792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 2); 88316d9e3a6SLisandro Dalcin } 884dd39110bSPierre 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)); 88516d9e3a6SLisandro Dalcin if (flg) { 8860f1074feSSatish Balay jac->relaxtype[2] = indx; 887792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 3); 88816d9e3a6SLisandro Dalcin } 88916d9e3a6SLisandro Dalcin 89016d9e3a6SLisandro Dalcin /* Relaxation Weight */ 8919566063dSJacob 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)); 89216d9e3a6SLisandro Dalcin if (flg) { 893792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxWt, jac->hsolver, tmpdbl); 89416d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 89516d9e3a6SLisandro Dalcin } 89616d9e3a6SLisandro Dalcin 89716d9e3a6SLisandro Dalcin n = 2; 89816d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 8999566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level", "Set the relaxation weight for a particular level (weight,level)", "None", twodbl, &n, &flg)); 90016d9e3a6SLisandro Dalcin if (flg) { 9010fdf79fbSJacob 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); 90216d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 903792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelRelaxWt, jac->hsolver, twodbl[0], indx); 90416d9e3a6SLisandro Dalcin } 90516d9e3a6SLisandro Dalcin 90616d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 9079566063dSJacob 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)); 90816d9e3a6SLisandro Dalcin if (flg) { 909792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOuterWt, jac->hsolver, tmpdbl); 91016d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 91116d9e3a6SLisandro Dalcin } 91216d9e3a6SLisandro Dalcin 91316d9e3a6SLisandro Dalcin n = 2; 91416d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 9159566063dSJacob 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)); 91616d9e3a6SLisandro Dalcin if (flg) { 9170fdf79fbSJacob 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); 91816d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 919792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelOuterWt, jac->hsolver, twodbl[0], indx); 92016d9e3a6SLisandro Dalcin } 92116d9e3a6SLisandro Dalcin 92216d9e3a6SLisandro Dalcin /* the Relax Order */ 9239566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg)); 92416d9e3a6SLisandro Dalcin 9258afaa268SBarry Smith if (flg && tmp_truth) { 92616d9e3a6SLisandro Dalcin jac->relaxorder = 0; 927792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 92816d9e3a6SLisandro Dalcin } 929dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type", "Measure type", "None", HYPREBoomerAMGMeasureType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType), HYPREBoomerAMGMeasureType[0], &indx, &flg)); 93016d9e3a6SLisandro Dalcin if (flg) { 93116d9e3a6SLisandro Dalcin jac->measuretype = indx; 932792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 93316d9e3a6SLisandro Dalcin } 9340f1074feSSatish Balay /* update list length 3/07 */ 935dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type", "Coarsen type", "None", HYPREBoomerAMGCoarsenType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType), HYPREBoomerAMGCoarsenType[6], &indx, &flg)); 93616d9e3a6SLisandro Dalcin if (flg) { 93716d9e3a6SLisandro Dalcin jac->coarsentype = indx; 938792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 93916d9e3a6SLisandro Dalcin } 9400f1074feSSatish Balay 9419566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg)); 94248a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 9439566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg)); 94448a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 945db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 946db6f9c32SMark Adams // global parameter but is closely associated with BoomerAMG 947dd39110bSPierre 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)); 9482d6c3ceeSStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 949db6f9c32SMark Adams if (!flg) indx = 0; 9509566063dSJacob Faibussowitsch PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, PCHYPRESpgemmTypes[indx])); 9512d6c3ceeSStefano Zampini #else 9522d6c3ceeSStefano Zampini PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, "hypre")); 9532d6c3ceeSStefano Zampini #endif 954db6f9c32SMark Adams #endif 955589dcaf0SStefano Zampini /* AIR */ 956589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 9579566063dSJacob 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)); 958792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 959589dcaf0SStefano Zampini if (jac->Rtype) { 96019be502cSAlexander HYPRE_Int **grid_relax_points = hypre_TAlloc(HYPRE_Int *, 4, HYPRE_MEMORY_HOST); 96119be502cSAlexander char *prerelax[256]; 96219be502cSAlexander char *postrelax[256]; 96319be502cSAlexander char stringF[2] = "F", stringC[2] = "C", stringA[2] = "A"; 96419be502cSAlexander PetscInt ns_down = 256, ns_up = 256; 96519be502cSAlexander PetscBool matchF, matchC, matchA; 96619be502cSAlexander 967589dcaf0SStefano 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 */ 968589dcaf0SStefano Zampini 9699566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR", "Threshold for R", "None", jac->Rstrongthreshold, &jac->Rstrongthreshold, NULL)); 970792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 971589dcaf0SStefano Zampini 9729566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR", "Filter threshold for R", "None", jac->Rfilterthreshold, &jac->Rfilterthreshold, NULL)); 973792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 974589dcaf0SStefano Zampini 9759566063dSJacob 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)); 976792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 977589dcaf0SStefano Zampini 9789566063dSJacob 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)); 979792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 98019be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_prerelax", "Defines prerelax scheme", "None", prerelax, &ns_down, NULL)); 98119be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_postrelax", "Defines postrelax scheme", "None", postrelax, &ns_up, NULL)); 98219be502cSAlexander 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"); 98319be502cSAlexander 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"); 98419be502cSAlexander 98519be502cSAlexander grid_relax_points[0] = NULL; 98619be502cSAlexander grid_relax_points[1] = hypre_TAlloc(HYPRE_Int, ns_down, HYPRE_MEMORY_HOST); 98719be502cSAlexander grid_relax_points[2] = hypre_TAlloc(HYPRE_Int, ns_up, HYPRE_MEMORY_HOST); 98819be502cSAlexander grid_relax_points[3] = hypre_TAlloc(HYPRE_Int, jac->gridsweeps[2], HYPRE_MEMORY_HOST); 98919be502cSAlexander grid_relax_points[3][0] = 0; 99019be502cSAlexander 99119be502cSAlexander // set down relax scheme 99219be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) { 99319be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringF, &matchF)); 99419be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringC, &matchC)); 99519be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringA, &matchA)); 99619be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_prerelax are C, F, and A"); 99719be502cSAlexander if (matchF) grid_relax_points[1][i] = -1; 99819be502cSAlexander else if (matchC) grid_relax_points[1][i] = 1; 99919be502cSAlexander else if (matchA) grid_relax_points[1][i] = 0; 100019be502cSAlexander } 100119be502cSAlexander 100219be502cSAlexander // set up relax scheme 100319be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) { 100419be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringF, &matchF)); 100519be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringC, &matchC)); 100619be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringA, &matchA)); 100719be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_postrelax are C, F, and A"); 100819be502cSAlexander if (matchF) grid_relax_points[2][i] = -1; 100919be502cSAlexander else if (matchC) grid_relax_points[2][i] = 1; 101019be502cSAlexander else if (matchA) grid_relax_points[2][i] = 0; 101119be502cSAlexander } 101219be502cSAlexander 101319be502cSAlexander // set coarse relax scheme 101419be502cSAlexander for (PetscInt i = 0; i < jac->gridsweeps[2]; i++) grid_relax_points[3][i] = 0; 101519be502cSAlexander 101619be502cSAlexander // Pass relax schemes to hypre 101719be502cSAlexander PetscCallExternal(HYPRE_BoomerAMGSetGridRelaxPoints, jac->hsolver, grid_relax_points); 101819be502cSAlexander 101919be502cSAlexander // cleanup memory 102019be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) PetscCall(PetscFree(prerelax[i])); 102119be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) PetscCall(PetscFree(postrelax[i])); 1022589dcaf0SStefano Zampini } 1023589dcaf0SStefano Zampini #endif 1024589dcaf0SStefano Zampini 1025ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9, 9, 9) 102663a3b9bcSJacob 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); 1027ecae95adSPierre Jolivet #endif 1028ecae95adSPierre Jolivet 10290f1074feSSatish Balay /* new 3/07 */ 1030dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type", "Interpolation type", "None", HYPREBoomerAMGInterpType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType), HYPREBoomerAMGInterpType[0], &indx, &flg)); 1031589dcaf0SStefano Zampini if (flg || jac->Rtype) { 1032589dcaf0SStefano Zampini if (flg) jac->interptype = indx; 1033792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 10340f1074feSSatish Balay } 10350f1074feSSatish Balay 10369566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", &flg)); 103716d9e3a6SLisandro Dalcin if (flg) { 1038b96a4a96SBarry Smith level = 3; 10399566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", level, &level, NULL)); 10402fa5cd67SKarl Rupp 1041b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1042792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel, jac->hsolver, level); 10432ae77aedSBarry Smith } 10442ae77aedSBarry Smith 10459566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", &flg)); 10462ae77aedSBarry Smith if (flg) { 1047b96a4a96SBarry Smith level = 3; 10489566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", level, &level, NULL)); 10492fa5cd67SKarl Rupp 1050b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1051792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDebugFlag, jac->hsolver, level); 105216d9e3a6SLisandro Dalcin } 10538f87f92bSBarry Smith 10549566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg)); 10558f87f92bSBarry Smith if (flg && tmp_truth) { 10568f87f92bSBarry Smith PetscInt tmp_int; 10579566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", jac->nodal_relax_levels, &tmp_int, &flg)); 10588f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 1059792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, 6); 1060792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDomainType, jac->hsolver, 1); 1061792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOverlap, jac->hsolver, 0); 1062792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, jac->nodal_relax_levels); 10638f87f92bSBarry Smith } 10648f87f92bSBarry Smith 10659566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL)); 1066792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 1067589dcaf0SStefano Zampini 1068589dcaf0SStefano Zampini /* options for ParaSails solvers */ 1069dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flg)); 1070589dcaf0SStefano Zampini if (flg) { 1071589dcaf0SStefano Zampini jac->symt = indx; 1072792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSym, jac->hsolver, jac->symt); 1073589dcaf0SStefano Zampini } 1074589dcaf0SStefano Zampini 1075d0609cedSBarry Smith PetscOptionsHeadEnd(); 10763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 107716d9e3a6SLisandro Dalcin } 107816d9e3a6SLisandro Dalcin 1079d71ae5a4SJacob 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) 1080d71ae5a4SJacob Faibussowitsch { 108116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 10822cf14000SStefano Zampini HYPRE_Int oits; 108316d9e3a6SLisandro Dalcin 108416d9e3a6SLisandro Dalcin PetscFunctionBegin; 10859566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 1086792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, its * jac->maxiter); 1087792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, rtol); 108816d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 10899566063dSJacob Faibussowitsch PetscCall(PCApply_HYPRE(pc, b, y)); 109016d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 1091792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGGetNumIterations, jac->hsolver, &oits); 10924d0a8057SBarry Smith *outits = oits; 10934d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 10944d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1095792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 1096792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 10973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 109816d9e3a6SLisandro Dalcin } 109916d9e3a6SLisandro Dalcin 1100d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc, PetscViewer viewer) 1101d71ae5a4SJacob Faibussowitsch { 110216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1103ace3abfcSBarry Smith PetscBool iascii; 110416d9e3a6SLisandro Dalcin 110516d9e3a6SLisandro Dalcin PetscFunctionBegin; 11069566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 110716d9e3a6SLisandro Dalcin if (iascii) { 11089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE BoomerAMG preconditioning\n")); 11099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Cycle type %s\n", HYPREBoomerAMGCycleType[jac->cycletype])); 111063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of levels %" PetscInt_FMT "\n", jac->maxlevels)); 111163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of iterations PER hypre call %" PetscInt_FMT "\n", jac->maxiter)); 11129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Convergence tolerance PER hypre call %g\n", (double)jac->tol)); 11139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for strong coupling %g\n", (double)jac->strongthreshold)); 11149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation truncation factor %g\n", (double)jac->truncfactor)); 111563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: max elements per row %" PetscInt_FMT "\n", jac->pmax)); 111648a46eb9SPierre Jolivet if (jac->interp_refine) PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n", jac->interp_refine)); 111763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of levels of aggressive coarsening %" PetscInt_FMT "\n", jac->agg_nl)); 111863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of paths for aggressive coarsening %" PetscInt_FMT "\n", jac->agg_num_paths)); 11190f1074feSSatish Balay 11209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum row sums %g\n", (double)jac->maxrowsum)); 112116d9e3a6SLisandro Dalcin 112263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps down %" PetscInt_FMT "\n", jac->gridsweeps[0])); 112363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps up %" PetscInt_FMT "\n", jac->gridsweeps[1])); 112463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps on coarse %" PetscInt_FMT "\n", jac->gridsweeps[2])); 112516d9e3a6SLisandro Dalcin 11269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax down %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[0]])); 11279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax up %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[1]])); 11289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax on coarse %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[2]])); 112916d9e3a6SLisandro Dalcin 11309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax weight (all) %g\n", (double)jac->relaxweight)); 11319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Outer relax weight (all) %g\n", (double)jac->outerrelaxweight)); 113216d9e3a6SLisandro Dalcin 113319be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum size of coarsest grid %" PetscInt_FMT "\n", jac->maxc)); 113419be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Minimum size of coarsest grid %" PetscInt_FMT "\n", jac->minc)); 113519be502cSAlexander 113616d9e3a6SLisandro Dalcin if (jac->relaxorder) { 11379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using CF-relaxation\n")); 113816d9e3a6SLisandro Dalcin } else { 11399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using CF-relaxation\n")); 114016d9e3a6SLisandro Dalcin } 11416a251517SEike Mueller if (jac->smoothtype != -1) { 11429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth type %s\n", HYPREBoomerAMGSmoothType[jac->smoothtype])); 114363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num levels %" PetscInt_FMT "\n", jac->smoothnumlevels)); 11447e352d70SEike Mueller } else { 11459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using more complex smoothers.\n")); 11461810e44eSEike Mueller } 11471810e44eSEike Mueller if (jac->smoothtype == 3) { 114863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) levels %" PetscInt_FMT "\n", jac->eu_level)); 11499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) drop tolerance %g\n", (double)jac->eu_droptolerance)); 115063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 11516a251517SEike Mueller } 11529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Measure type %s\n", HYPREBoomerAMGMeasureType[jac->measuretype])); 11539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Coarsen type %s\n", HYPREBoomerAMGCoarsenType[jac->coarsentype])); 11549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation type %s\n", jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt")); 115548a46eb9SPierre Jolivet if (jac->nodal_coarsening) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n", jac->nodal_coarsening)); 11565272c319SBarry Smith if (jac->vec_interp_variant) { 115763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n", jac->vec_interp_variant)); 115863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n", jac->vec_interp_qmax)); 11599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n", jac->vec_interp_smooth)); 11608f87f92bSBarry Smith } 116148a46eb9SPierre Jolivet if (jac->nodal_relax) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n", jac->nodal_relax_levels)); 1162db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 11639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", jac->spgemm_type)); 11642d6c3ceeSStefano Zampini #else 11652d6c3ceeSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", "hypre")); 1166db6f9c32SMark Adams #endif 1167589dcaf0SStefano Zampini /* AIR */ 1168589dcaf0SStefano Zampini if (jac->Rtype) { 116963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using approximate ideal restriction type %" PetscInt_FMT "\n", jac->Rtype)); 11709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for R %g\n", (double)jac->Rstrongthreshold)); 11719566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Filter for R %g\n", (double)jac->Rfilterthreshold)); 11729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop tolerance %g\n", (double)jac->Adroptol)); 117363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop type %" PetscInt_FMT "\n", jac->Adroptype)); 1174589dcaf0SStefano Zampini } 117516d9e3a6SLisandro Dalcin } 11763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 117716d9e3a6SLisandro Dalcin } 117816d9e3a6SLisandro Dalcin 1179d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc, PetscOptionItems *PetscOptionsObject) 1180d71ae5a4SJacob Faibussowitsch { 118116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 11824ddd07fcSJed Brown PetscInt indx; 1183ace3abfcSBarry Smith PetscBool flag; 118416d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 118516d9e3a6SLisandro Dalcin 118616d9e3a6SLisandro Dalcin PetscFunctionBegin; 1187d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ParaSails Options"); 11889566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels", "Number of number of levels", "None", jac->nlevels, &jac->nlevels, 0)); 11899566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh", "Threshold", "None", jac->threshold, &jac->threshold, &flag)); 1190792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 119116d9e3a6SLisandro Dalcin 11929566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter", "filter", "None", jac->filter, &jac->filter, &flag)); 1193792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 119416d9e3a6SLisandro Dalcin 11959566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal", "Load balance", "None", jac->loadbal, &jac->loadbal, &flag)); 1196792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 119716d9e3a6SLisandro Dalcin 11989566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging", "Print info to screen", "None", (PetscBool)jac->logging, (PetscBool *)&jac->logging, &flag)); 1199792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 120016d9e3a6SLisandro Dalcin 12019566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse", "Reuse nonzero pattern in preconditioner", "None", (PetscBool)jac->ruse, (PetscBool *)&jac->ruse, &flag)); 1202792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 120316d9e3a6SLisandro Dalcin 1204dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flag)); 120516d9e3a6SLisandro Dalcin if (flag) { 120616d9e3a6SLisandro Dalcin jac->symt = indx; 1207792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 120816d9e3a6SLisandro Dalcin } 120916d9e3a6SLisandro Dalcin 1210d0609cedSBarry Smith PetscOptionsHeadEnd(); 12113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 121216d9e3a6SLisandro Dalcin } 121316d9e3a6SLisandro Dalcin 1214d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ParaSails(PC pc, PetscViewer viewer) 1215d71ae5a4SJacob Faibussowitsch { 121616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1217ace3abfcSBarry Smith PetscBool iascii; 1218feb237baSPierre Jolivet const char *symt = 0; 121916d9e3a6SLisandro Dalcin 122016d9e3a6SLisandro Dalcin PetscFunctionBegin; 12219566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 122216d9e3a6SLisandro Dalcin if (iascii) { 12239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ParaSails preconditioning\n")); 122463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " nlevels %" PetscInt_FMT "\n", jac->nlevels)); 12259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " threshold %g\n", (double)jac->threshold)); 12269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " filter %g\n", (double)jac->filter)); 12279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " load balance %g\n", (double)jac->loadbal)); 12289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " reuse nonzero structure %s\n", PetscBools[jac->ruse])); 12299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " print info to screen %s\n", PetscBools[jac->logging])); 12302fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 12312fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 12322fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 123363a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONG, "Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT, jac->symt); 12349566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", symt)); 123516d9e3a6SLisandro Dalcin } 12363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 123716d9e3a6SLisandro Dalcin } 1238f1580f4eSBarry Smith 1239d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc, PetscOptionItems *PetscOptionsObject) 1240d71ae5a4SJacob Faibussowitsch { 12414cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 12424cb006feSStefano Zampini PetscInt n; 12434cb006feSStefano Zampini PetscBool flag, flag2, flag3, flag4; 12444cb006feSStefano Zampini 12454cb006feSStefano Zampini PetscFunctionBegin; 1246d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE AMS Options"); 12479566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level", "Debugging output level for AMS", "None", jac->as_print, &jac->as_print, &flag)); 1248792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 12499566063dSJacob 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)); 1250792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 12519566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type", "Cycle type for AMS multigrid", "None", jac->ams_cycle_type, &jac->ams_cycle_type, &flag)); 1252792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 12539566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_tol", "Error tolerance for AMS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1254792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 12559566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type", "Relaxation type for AMS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 12569566063dSJacob 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)); 12579566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight", "Relaxation weight for AMS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 12589566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_omega", "SSOR coefficient for AMS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 125948a46eb9SPierre 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); 12609566063dSJacob 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)); 12614cb006feSStefano Zampini n = 5; 12629566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options", "AMG options for vector Poisson", "None", jac->as_amg_alpha_opts, &n, &flag2)); 12634cb006feSStefano Zampini if (flag || flag2) { 1264792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1265863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1266863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 12679371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1268a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 12694cb006feSStefano Zampini } 12709566063dSJacob 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)); 12714cb006feSStefano Zampini n = 5; 12729566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options", "AMG options for scalar Poisson solver", "None", jac->as_amg_beta_opts, &n, &flag2)); 12734cb006feSStefano Zampini if (flag || flag2) { 1274792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1275863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1276863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 12779371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1278a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 12794cb006feSStefano Zampini } 12809566063dSJacob 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)); 128123df4f25SStefano Zampini if (flag) { /* override HYPRE's default only if the options is used */ 1282792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetProjectionFrequency, jac->hsolver, jac->ams_proj_freq); 128323df4f25SStefano Zampini } 1284d0609cedSBarry Smith PetscOptionsHeadEnd(); 12853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12864cb006feSStefano Zampini } 12874cb006feSStefano Zampini 1288d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_AMS(PC pc, PetscViewer viewer) 1289d71ae5a4SJacob Faibussowitsch { 12904cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 12914cb006feSStefano Zampini PetscBool iascii; 12924cb006feSStefano Zampini 12934cb006feSStefano Zampini PetscFunctionBegin; 12949566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 12954cb006feSStefano Zampini if (iascii) { 12969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE AMS preconditioning\n")); 129763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 129863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 129963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 130063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 130163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 130263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 130363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 13044cb006feSStefano Zampini if (jac->alpha_Poisson) { 13059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (passed in by user)\n")); 13064cb006feSStefano Zampini } else { 13079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (computed) \n")); 13084cb006feSStefano Zampini } 130963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 131063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 131163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 131263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 131363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 131463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 13154cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 13164cb006feSStefano Zampini if (jac->beta_Poisson) { 13179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (passed in by user)\n")); 13184cb006feSStefano Zampini } else { 13199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (computed) \n")); 13204cb006feSStefano Zampini } 132163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 132263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 132363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 132463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 132563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 132663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_beta_theta)); 132748a46eb9SPierre 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)); 132823df4f25SStefano Zampini } else { 13299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver not used (zero-conductivity everywhere) \n")); 13304cb006feSStefano Zampini } 13314cb006feSStefano Zampini } 13323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13334cb006feSStefano Zampini } 13344cb006feSStefano Zampini 1335d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PC pc, PetscOptionItems *PetscOptionsObject) 1336d71ae5a4SJacob Faibussowitsch { 1337863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1338863406b8SStefano Zampini PetscInt n; 1339863406b8SStefano Zampini PetscBool flag, flag2, flag3, flag4; 1340863406b8SStefano Zampini 1341863406b8SStefano Zampini PetscFunctionBegin; 1342d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ADS Options"); 13439566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level", "Debugging output level for ADS", "None", jac->as_print, &jac->as_print, &flag)); 1344792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 13459566063dSJacob 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)); 1346792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 13479566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type", "Cycle type for ADS multigrid", "None", jac->ads_cycle_type, &jac->ads_cycle_type, &flag)); 1348792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ads_cycle_type); 13499566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_tol", "Error tolerance for ADS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1350792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 13519566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type", "Relaxation type for ADS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 13529566063dSJacob 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)); 13539566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight", "Relaxation weight for ADS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 13549566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_omega", "SSOR coefficient for ADS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 135548a46eb9SPierre 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); 13569566063dSJacob 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)); 1357863406b8SStefano Zampini n = 5; 13589566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options", "AMG options for AMS solver inside ADS", "None", jac->as_amg_alpha_opts, &n, &flag2)); 13599566063dSJacob 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)); 1360863406b8SStefano Zampini if (flag || flag2 || flag3) { 1361792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMS cycle type */ 1362863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1363863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1364863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 13659371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1366a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 1367863406b8SStefano Zampini } 13689566063dSJacob 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)); 1369863406b8SStefano Zampini n = 5; 13709566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options", "AMG options for vector AMG solver inside ADS", "None", jac->as_amg_beta_opts, &n, &flag2)); 1371863406b8SStefano Zampini if (flag || flag2) { 1372792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1373863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1374863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 13759371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1376a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 1377863406b8SStefano Zampini } 1378d0609cedSBarry Smith PetscOptionsHeadEnd(); 13793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1380863406b8SStefano Zampini } 1381863406b8SStefano Zampini 1382d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ADS(PC pc, PetscViewer viewer) 1383d71ae5a4SJacob Faibussowitsch { 1384863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1385863406b8SStefano Zampini PetscBool iascii; 1386863406b8SStefano Zampini 1387863406b8SStefano Zampini PetscFunctionBegin; 13889566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1389863406b8SStefano Zampini if (iascii) { 13909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ADS preconditioning\n")); 139163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 139263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ads_cycle_type)); 139363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 139463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 139563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 139663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 139763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 13989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " AMS solver using boomerAMG\n")); 139963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 140063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 140163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 140263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 140363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 140463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 140563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 14069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver using boomerAMG\n")); 140763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 140863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 140963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 141063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 141163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 141263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_beta_theta)); 1413863406b8SStefano Zampini } 14143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1415863406b8SStefano Zampini } 1416863406b8SStefano Zampini 1417d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G) 1418d71ae5a4SJacob Faibussowitsch { 14194cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 14205ac14e1cSStefano Zampini PetscBool ishypre; 14214cb006feSStefano Zampini 14224cb006feSStefano Zampini PetscFunctionBegin; 14239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)G, MATHYPRE, &ishypre)); 14245ac14e1cSStefano Zampini if (ishypre) { 14259566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)G)); 14269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 14275ac14e1cSStefano Zampini jac->G = G; 14285ac14e1cSStefano Zampini } else { 14299566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 14309566063dSJacob Faibussowitsch PetscCall(MatConvert(G, MATHYPRE, MAT_INITIAL_MATRIX, &jac->G)); 14315ac14e1cSStefano Zampini } 14323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14334cb006feSStefano Zampini } 14344cb006feSStefano Zampini 14354cb006feSStefano Zampini /*@ 1436f1580f4eSBarry Smith PCHYPRESetDiscreteGradient - Set discrete gradient matrix for `PCHYPRE` type of ams or ads 14374cb006feSStefano Zampini 1438c3339decSBarry Smith Collective 14394cb006feSStefano Zampini 14404cb006feSStefano Zampini Input Parameters: 14414cb006feSStefano Zampini + pc - the preconditioning context 14424cb006feSStefano Zampini - G - the discrete gradient 14434cb006feSStefano Zampini 14444cb006feSStefano Zampini Level: intermediate 14454cb006feSStefano Zampini 144695452b02SPatrick Sanan Notes: 144795452b02SPatrick Sanan G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 1448147403d9SBarry Smith 1449863406b8SStefano 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 14504cb006feSStefano Zampini 1451feefa0e1SJacob Faibussowitsch Developer Notes: 1452f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1453f1580f4eSBarry Smith 1454562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteCurl()` 14554cb006feSStefano Zampini @*/ 1456d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 1457d71ae5a4SJacob Faibussowitsch { 14584cb006feSStefano Zampini PetscFunctionBegin; 14594cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 14604cb006feSStefano Zampini PetscValidHeaderSpecific(G, MAT_CLASSID, 2); 14614cb006feSStefano Zampini PetscCheckSameComm(pc, 1, G, 2); 1462cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteGradient_C", (PC, Mat), (pc, G)); 14633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14644cb006feSStefano Zampini } 14654cb006feSStefano Zampini 1466d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C) 1467d71ae5a4SJacob Faibussowitsch { 1468863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 14695ac14e1cSStefano Zampini PetscBool ishypre; 1470863406b8SStefano Zampini 1471863406b8SStefano Zampini PetscFunctionBegin; 14729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C, MATHYPRE, &ishypre)); 14735ac14e1cSStefano Zampini if (ishypre) { 14749566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)C)); 14759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 14765ac14e1cSStefano Zampini jac->C = C; 14775ac14e1cSStefano Zampini } else { 14789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 14799566063dSJacob Faibussowitsch PetscCall(MatConvert(C, MATHYPRE, MAT_INITIAL_MATRIX, &jac->C)); 14805ac14e1cSStefano Zampini } 14813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1482863406b8SStefano Zampini } 1483863406b8SStefano Zampini 1484863406b8SStefano Zampini /*@ 1485f1580f4eSBarry Smith PCHYPRESetDiscreteCurl - Set discrete curl matrx for `PCHYPRE` type of ads 1486863406b8SStefano Zampini 1487c3339decSBarry Smith Collective 1488863406b8SStefano Zampini 1489863406b8SStefano Zampini Input Parameters: 1490863406b8SStefano Zampini + pc - the preconditioning context 1491863406b8SStefano Zampini - C - the discrete curl 1492863406b8SStefano Zampini 1493863406b8SStefano Zampini Level: intermediate 1494863406b8SStefano Zampini 149595452b02SPatrick Sanan Notes: 149695452b02SPatrick Sanan C should have as many rows as the number of faces and as many columns as the number of edges in the mesh 1497147403d9SBarry Smith 1498863406b8SStefano Zampini Each row of G has as many nonzeros as the number of edges of a face, with column indexes being the global indexes of the corresponding edge: matrix entries are +1 and -1 depending on edge orientation with respect to the face orientation 1499863406b8SStefano Zampini 1500feefa0e1SJacob Faibussowitsch Developer Notes: 1501f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1502f1580f4eSBarry Smith 1503f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ads it should be called `PCHYPREADSSetDiscreteCurl()` 1504f1580f4eSBarry Smith 1505562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()` 1506863406b8SStefano Zampini @*/ 1507d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C) 1508d71ae5a4SJacob Faibussowitsch { 1509863406b8SStefano Zampini PetscFunctionBegin; 1510863406b8SStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1511863406b8SStefano Zampini PetscValidHeaderSpecific(C, MAT_CLASSID, 2); 1512863406b8SStefano Zampini PetscCheckSameComm(pc, 1, C, 2); 1513cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteCurl_C", (PC, Mat), (pc, C)); 15143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1515863406b8SStefano Zampini } 1516863406b8SStefano Zampini 1517d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1518d71ae5a4SJacob Faibussowitsch { 15196bf688a0SCe Qin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 15206bf688a0SCe Qin PetscBool ishypre; 15216bf688a0SCe Qin PetscInt i; 15226bf688a0SCe Qin PetscFunctionBegin; 15236bf688a0SCe Qin 15249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 15259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 15266bf688a0SCe Qin for (i = 0; i < 3; ++i) { 15279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[i])); 15289566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[i])); 15296bf688a0SCe Qin } 15306bf688a0SCe Qin 15316bf688a0SCe Qin jac->dim = dim; 15326bf688a0SCe Qin if (RT_PiFull) { 15339566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_PiFull, MATHYPRE, &ishypre)); 15346bf688a0SCe Qin if (ishypre) { 15359566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_PiFull)); 15366bf688a0SCe Qin jac->RT_PiFull = RT_PiFull; 15376bf688a0SCe Qin } else { 15389566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_PiFull)); 15396bf688a0SCe Qin } 15406bf688a0SCe Qin } 15416bf688a0SCe Qin if (RT_Pi) { 15426bf688a0SCe Qin for (i = 0; i < dim; ++i) { 15436bf688a0SCe Qin if (RT_Pi[i]) { 15449566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_Pi[i], MATHYPRE, &ishypre)); 15456bf688a0SCe Qin if (ishypre) { 15469566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_Pi[i])); 15476bf688a0SCe Qin jac->RT_Pi[i] = RT_Pi[i]; 15486bf688a0SCe Qin } else { 15499566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_Pi[i])); 15506bf688a0SCe Qin } 15516bf688a0SCe Qin } 15526bf688a0SCe Qin } 15536bf688a0SCe Qin } 15546bf688a0SCe Qin if (ND_PiFull) { 15559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_PiFull, MATHYPRE, &ishypre)); 15566bf688a0SCe Qin if (ishypre) { 15579566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_PiFull)); 15586bf688a0SCe Qin jac->ND_PiFull = ND_PiFull; 15596bf688a0SCe Qin } else { 15609566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_PiFull)); 15616bf688a0SCe Qin } 15626bf688a0SCe Qin } 15636bf688a0SCe Qin if (ND_Pi) { 15646bf688a0SCe Qin for (i = 0; i < dim; ++i) { 15656bf688a0SCe Qin if (ND_Pi[i]) { 15669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_Pi[i], MATHYPRE, &ishypre)); 15676bf688a0SCe Qin if (ishypre) { 15689566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_Pi[i])); 15696bf688a0SCe Qin jac->ND_Pi[i] = ND_Pi[i]; 15706bf688a0SCe Qin } else { 15719566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_Pi[i])); 15726bf688a0SCe Qin } 15736bf688a0SCe Qin } 15746bf688a0SCe Qin } 15756bf688a0SCe Qin } 15766bf688a0SCe Qin 15773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15786bf688a0SCe Qin } 15796bf688a0SCe Qin 15806bf688a0SCe Qin /*@ 1581f1580f4eSBarry Smith PCHYPRESetInterpolations - Set interpolation matrices for `PCHYPRE` type of ams or ads 15826bf688a0SCe Qin 1583c3339decSBarry Smith Collective 15846bf688a0SCe Qin 15856bf688a0SCe Qin Input Parameters: 15866bf688a0SCe Qin + pc - the preconditioning context 15872fe279fdSBarry Smith . dim - the dimension of the problem, only used in AMS 15882fe279fdSBarry Smith . RT_PiFull - Raviart-Thomas interpolation matrix 15892fe279fdSBarry Smith . RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix 15902fe279fdSBarry Smith . ND_PiFull - Nedelec interpolation matrix 15916bf688a0SCe Qin - ND_Pi - x/y/z component of Nedelec interpolation matrix 15926bf688a0SCe Qin 1593f1580f4eSBarry Smith Level: intermediate 1594f1580f4eSBarry Smith 159595452b02SPatrick Sanan Notes: 159695452b02SPatrick Sanan For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL. 1597147403d9SBarry Smith 15986bf688a0SCe Qin For ADS, both type of interpolation matrices are needed. 1599147403d9SBarry Smith 1600feefa0e1SJacob Faibussowitsch Developer Notes: 1601f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 16026bf688a0SCe Qin 1603562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE` 16046bf688a0SCe Qin @*/ 1605d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1606d71ae5a4SJacob Faibussowitsch { 16076bf688a0SCe Qin PetscInt i; 16086bf688a0SCe Qin 16096bf688a0SCe Qin PetscFunctionBegin; 16106bf688a0SCe Qin PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 16116bf688a0SCe Qin if (RT_PiFull) { 16126bf688a0SCe Qin PetscValidHeaderSpecific(RT_PiFull, MAT_CLASSID, 3); 16136bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_PiFull, 3); 16146bf688a0SCe Qin } 16156bf688a0SCe Qin if (RT_Pi) { 16164f572ea9SToby Isaac PetscAssertPointer(RT_Pi, 4); 16176bf688a0SCe Qin for (i = 0; i < dim; ++i) { 16186bf688a0SCe Qin if (RT_Pi[i]) { 16196bf688a0SCe Qin PetscValidHeaderSpecific(RT_Pi[i], MAT_CLASSID, 4); 16206bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_Pi[i], 4); 16216bf688a0SCe Qin } 16226bf688a0SCe Qin } 16236bf688a0SCe Qin } 16246bf688a0SCe Qin if (ND_PiFull) { 16256bf688a0SCe Qin PetscValidHeaderSpecific(ND_PiFull, MAT_CLASSID, 5); 16266bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_PiFull, 5); 16276bf688a0SCe Qin } 16286bf688a0SCe Qin if (ND_Pi) { 16294f572ea9SToby Isaac PetscAssertPointer(ND_Pi, 6); 16306bf688a0SCe Qin for (i = 0; i < dim; ++i) { 16316bf688a0SCe Qin if (ND_Pi[i]) { 16326bf688a0SCe Qin PetscValidHeaderSpecific(ND_Pi[i], MAT_CLASSID, 6); 16336bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_Pi[i], 6); 16346bf688a0SCe Qin } 16356bf688a0SCe Qin } 16366bf688a0SCe Qin } 1637cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetInterpolations_C", (PC, PetscInt, Mat, Mat[], Mat, Mat[]), (pc, dim, RT_PiFull, RT_Pi, ND_PiFull, ND_Pi)); 16383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16396bf688a0SCe Qin } 16406bf688a0SCe Qin 1641d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha) 1642d71ae5a4SJacob Faibussowitsch { 16434cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 16445ac14e1cSStefano Zampini PetscBool ishypre; 16454cb006feSStefano Zampini 16464cb006feSStefano Zampini PetscFunctionBegin; 16479566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 16485ac14e1cSStefano Zampini if (ishypre) { 16495ac14e1cSStefano Zampini if (isalpha) { 16509566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 16519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 16525ac14e1cSStefano Zampini jac->alpha_Poisson = A; 16535ac14e1cSStefano Zampini } else { 16545ac14e1cSStefano Zampini if (A) { 16559566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 16565ac14e1cSStefano Zampini } else { 16575ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 16585ac14e1cSStefano Zampini } 16599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16605ac14e1cSStefano Zampini jac->beta_Poisson = A; 16615ac14e1cSStefano Zampini } 16625ac14e1cSStefano Zampini } else { 16635ac14e1cSStefano Zampini if (isalpha) { 16649566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 16659566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->alpha_Poisson)); 16665ac14e1cSStefano Zampini } else { 16675ac14e1cSStefano Zampini if (A) { 16689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16699566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->beta_Poisson)); 16705ac14e1cSStefano Zampini } else { 16719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16725ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 16735ac14e1cSStefano Zampini } 16745ac14e1cSStefano Zampini } 16755ac14e1cSStefano Zampini } 16763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16774cb006feSStefano Zampini } 16784cb006feSStefano Zampini 16794cb006feSStefano Zampini /*@ 1680f1580f4eSBarry Smith PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix for `PCHYPRE` of type ams 16814cb006feSStefano Zampini 1682c3339decSBarry Smith Collective 16834cb006feSStefano Zampini 16844cb006feSStefano Zampini Input Parameters: 16854cb006feSStefano Zampini + pc - the preconditioning context 16864cb006feSStefano Zampini - A - the matrix 16874cb006feSStefano Zampini 16884cb006feSStefano Zampini Level: intermediate 16894cb006feSStefano Zampini 1690f1580f4eSBarry Smith Note: 169195452b02SPatrick Sanan A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 16924cb006feSStefano Zampini 1693feefa0e1SJacob Faibussowitsch Developer Notes: 1694f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1695f1580f4eSBarry Smith 1696f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetAlphaPoissonMatrix()` 1697f1580f4eSBarry Smith 1698562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()` 16994cb006feSStefano Zampini @*/ 1700d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 1701d71ae5a4SJacob Faibussowitsch { 17024cb006feSStefano Zampini PetscFunctionBegin; 17034cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 17044cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 17054cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 1706cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_TRUE)); 17073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17084cb006feSStefano Zampini } 17094cb006feSStefano Zampini 17104cb006feSStefano Zampini /*@ 1711f1580f4eSBarry Smith PCHYPRESetBetaPoissonMatrix - Set Poisson matrix for `PCHYPRE` of type ams 17124cb006feSStefano Zampini 1713c3339decSBarry Smith Collective 17144cb006feSStefano Zampini 17154cb006feSStefano Zampini Input Parameters: 17164cb006feSStefano Zampini + pc - the preconditioning context 1717f1580f4eSBarry Smith - A - the matrix, or NULL to turn it off 17184cb006feSStefano Zampini 17194cb006feSStefano Zampini Level: intermediate 17204cb006feSStefano Zampini 1721f1580f4eSBarry Smith Note: 172295452b02SPatrick Sanan A should be obtained by discretizing the Poisson problem with linear finite elements. 17234cb006feSStefano Zampini 1724feefa0e1SJacob Faibussowitsch Developer Notes: 1725f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1726f1580f4eSBarry Smith 1727f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSPCHYPRESetBetaPoissonMatrix()` 1728f1580f4eSBarry Smith 1729562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 17304cb006feSStefano Zampini @*/ 1731d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 1732d71ae5a4SJacob Faibussowitsch { 17334cb006feSStefano Zampini PetscFunctionBegin; 17344cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 17354cb006feSStefano Zampini if (A) { 17364cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 17374cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 17384cb006feSStefano Zampini } 1739cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_FALSE)); 17403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17414cb006feSStefano Zampini } 17424cb006feSStefano Zampini 1743d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc, Vec ozz, Vec zoz, Vec zzo) 1744d71ae5a4SJacob Faibussowitsch { 17454cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 17464cb006feSStefano Zampini 17474cb006feSStefano Zampini PetscFunctionBegin; 17484cb006feSStefano Zampini /* throw away any vector if already set */ 17499566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 17509566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 17519566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 17529566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(ozz->map, &jac->constants[0])); 17539566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(ozz, jac->constants[0])); 17549566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zoz->map, &jac->constants[1])); 17559566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zoz, jac->constants[1])); 17565ac14e1cSStefano Zampini jac->dim = 2; 17574cb006feSStefano Zampini if (zzo) { 17589566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zzo->map, &jac->constants[2])); 17599566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zzo, jac->constants[2])); 17605ac14e1cSStefano Zampini jac->dim++; 17614cb006feSStefano Zampini } 17623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17634cb006feSStefano Zampini } 17644cb006feSStefano Zampini 17654cb006feSStefano Zampini /*@ 1766f1580f4eSBarry Smith PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis for `PCHYPRE` of type ams 17674cb006feSStefano Zampini 1768c3339decSBarry Smith Collective 17694cb006feSStefano Zampini 17704cb006feSStefano Zampini Input Parameters: 17714cb006feSStefano Zampini + pc - the preconditioning context 17722fe279fdSBarry Smith . ozz - vector representing (1,0,0) (or (1,0) in 2D) 17732fe279fdSBarry Smith . zoz - vector representing (0,1,0) (or (0,1) in 2D) 17744cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 17754cb006feSStefano Zampini 17764cb006feSStefano Zampini Level: intermediate 17774cb006feSStefano Zampini 1778feefa0e1SJacob Faibussowitsch Developer Notes: 1779f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetEdgeConstantVectors()` 1780f1580f4eSBarry Smith 1781562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 17824cb006feSStefano Zampini @*/ 1783d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 1784d71ae5a4SJacob Faibussowitsch { 17854cb006feSStefano Zampini PetscFunctionBegin; 17864cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 17874cb006feSStefano Zampini PetscValidHeaderSpecific(ozz, VEC_CLASSID, 2); 17884cb006feSStefano Zampini PetscValidHeaderSpecific(zoz, VEC_CLASSID, 3); 17894cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo, VEC_CLASSID, 4); 17904cb006feSStefano Zampini PetscCheckSameComm(pc, 1, ozz, 2); 17914cb006feSStefano Zampini PetscCheckSameComm(pc, 1, zoz, 3); 17924cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc, 1, zzo, 4); 1793cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetEdgeConstantVectors_C", (PC, Vec, Vec, Vec), (pc, ozz, zoz, zzo)); 17943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17954cb006feSStefano Zampini } 17964cb006feSStefano Zampini 1797d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREAMSSetInteriorNodes_HYPRE(PC pc, Vec interior) 1798d71ae5a4SJacob Faibussowitsch { 1799be14dc20SKerry Key PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1800be14dc20SKerry Key 1801be14dc20SKerry Key PetscFunctionBegin; 1802be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 1803be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCreate(interior->map, &jac->interior)); 1804be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCopy(interior, jac->interior)); 1805be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_TRUE; 18063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1807be14dc20SKerry Key } 1808be14dc20SKerry Key 1809be14dc20SKerry Key /*@ 1810f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes - Set the list of interior nodes to a zero-conductivity region for `PCHYPRE` of type ams 1811be14dc20SKerry Key 1812c3339decSBarry Smith Collective 1813be14dc20SKerry Key 1814be14dc20SKerry Key Input Parameters: 1815be14dc20SKerry Key + pc - the preconditioning context 1816be14dc20SKerry Key - interior - vector. node is interior if its entry in the array is 1.0. 1817be14dc20SKerry Key 1818be14dc20SKerry Key Level: intermediate 1819be14dc20SKerry Key 1820be14dc20SKerry Key Note: 1821f1580f4eSBarry Smith This calls `HYPRE_AMSSetInteriorNodes()` 1822f1580f4eSBarry Smith 1823feefa0e1SJacob Faibussowitsch Developer Notes: 1824f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetInteriorNodes()` 1825f1580f4eSBarry Smith 1826562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 1827be14dc20SKerry Key @*/ 1828d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREAMSSetInteriorNodes(PC pc, Vec interior) 1829d71ae5a4SJacob Faibussowitsch { 1830be14dc20SKerry Key PetscFunctionBegin; 1831be14dc20SKerry Key PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1832be14dc20SKerry Key PetscValidHeaderSpecific(interior, VEC_CLASSID, 2); 1833be14dc20SKerry Key PetscCheckSameComm(pc, 1, interior, 2); 1834be14dc20SKerry Key PetscTryMethod(pc, "PCHYPREAMSSetInteriorNodes_C", (PC, Vec), (pc, interior)); 18353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1836be14dc20SKerry Key } 1837be14dc20SKerry Key 1838d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 1839d71ae5a4SJacob Faibussowitsch { 18404cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 18414cb006feSStefano Zampini Vec tv; 18424cb006feSStefano Zampini PetscInt i; 18434cb006feSStefano Zampini 18444cb006feSStefano Zampini PetscFunctionBegin; 18454cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 18469566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 18479566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 18489566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 18495ac14e1cSStefano Zampini jac->dim = dim; 18505ac14e1cSStefano Zampini 18514cb006feSStefano Zampini /* compute IJ vector for coordinates */ 18529566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)pc), &tv)); 18539566063dSJacob Faibussowitsch PetscCall(VecSetType(tv, VECSTANDARD)); 18549566063dSJacob Faibussowitsch PetscCall(VecSetSizes(tv, nloc, PETSC_DECIDE)); 18554cb006feSStefano Zampini for (i = 0; i < dim; i++) { 18564cb006feSStefano Zampini PetscScalar *array; 18574cb006feSStefano Zampini PetscInt j; 18584cb006feSStefano Zampini 18599566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(tv->map, &jac->coords[i])); 18609566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(tv, &array)); 18616ea7df73SStefano Zampini for (j = 0; j < nloc; j++) array[j] = coords[j * dim + i]; 18629566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(tv, &array)); 18639566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(tv, jac->coords[i])); 18644cb006feSStefano Zampini } 18659566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tv)); 18663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18674cb006feSStefano Zampini } 18684cb006feSStefano Zampini 1869d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREGetType_HYPRE(PC pc, const char *name[]) 1870d71ae5a4SJacob Faibussowitsch { 187116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 187216d9e3a6SLisandro Dalcin 187316d9e3a6SLisandro Dalcin PetscFunctionBegin; 187416d9e3a6SLisandro Dalcin *name = jac->hypre_type; 18753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 187616d9e3a6SLisandro Dalcin } 187716d9e3a6SLisandro Dalcin 1878d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetType_HYPRE(PC pc, const char name[]) 1879d71ae5a4SJacob Faibussowitsch { 188016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1881ace3abfcSBarry Smith PetscBool flag; 188216d9e3a6SLisandro Dalcin 188316d9e3a6SLisandro Dalcin PetscFunctionBegin; 188416d9e3a6SLisandro Dalcin if (jac->hypre_type) { 18859566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, name, &flag)); 18865f80ce2aSJacob Faibussowitsch PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "Cannot reset the HYPRE preconditioner type once it has been set"); 18873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 188816d9e3a6SLisandro Dalcin } else { 18899566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->hypre_type)); 189016d9e3a6SLisandro Dalcin } 189116d9e3a6SLisandro Dalcin 189216d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 189316d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 189416d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 189516d9e3a6SLisandro Dalcin 18969566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("pilut", jac->hypre_type, &flag)); 189716d9e3a6SLisandro Dalcin if (flag) { 18989566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 1899792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRPilutCreate, jac->comm_hypre, &jac->hsolver); 190016d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 190116d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 190216d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 190316d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 190416d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 190516d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 19063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 190716d9e3a6SLisandro Dalcin } 19089566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("euclid", jac->hypre_type, &flag)); 1909db966c6cSHong Zhang if (flag) { 19104e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 19117de69702SBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Hypre Euclid does not support 64-bit indices"); 19128bf83915SBarry Smith #endif 19139566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 1914792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidCreate, jac->comm_hypre, &jac->hsolver); 1915db966c6cSHong Zhang pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 1916db966c6cSHong Zhang pc->ops->view = PCView_HYPRE_Euclid; 1917db966c6cSHong Zhang jac->destroy = HYPRE_EuclidDestroy; 1918db966c6cSHong Zhang jac->setup = HYPRE_EuclidSetup; 1919db966c6cSHong Zhang jac->solve = HYPRE_EuclidSolve; 1920db966c6cSHong Zhang jac->factorrowsize = PETSC_DEFAULT; 1921db966c6cSHong Zhang jac->eu_level = PETSC_DEFAULT; /* default */ 19223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1923db966c6cSHong Zhang } 19249566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("parasails", jac->hypre_type, &flag)); 192516d9e3a6SLisandro Dalcin if (flag) { 19269566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 1927792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsCreate, jac->comm_hypre, &jac->hsolver); 192816d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 192916d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 193016d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 193116d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 193216d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 193316d9e3a6SLisandro Dalcin /* initialize */ 193416d9e3a6SLisandro Dalcin jac->nlevels = 1; 19358966356dSPierre Jolivet jac->threshold = .1; 193616d9e3a6SLisandro Dalcin jac->filter = .1; 193716d9e3a6SLisandro Dalcin jac->loadbal = 0; 19382fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int)PETSC_TRUE; 19392fa5cd67SKarl Rupp else jac->logging = (int)PETSC_FALSE; 19402fa5cd67SKarl Rupp 194116d9e3a6SLisandro Dalcin jac->ruse = (int)PETSC_FALSE; 194216d9e3a6SLisandro Dalcin jac->symt = 0; 1943792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 1944792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 1945792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 1946792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 1947792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 1948792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 19493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 195016d9e3a6SLisandro Dalcin } 19519566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("boomeramg", jac->hypre_type, &flag)); 195216d9e3a6SLisandro Dalcin if (flag) { 1953792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGCreate, &jac->hsolver); 195416d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 195516d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 195616d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 195716d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 195885245615SPierre Jolivet pc->ops->matapply = PCMatApply_HYPRE_BoomerAMG; 19599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", PCGetInterpolations_BoomerAMG)); 19609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", PCGetCoarseOperators_BoomerAMG)); 196116d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 196216d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 196316d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 196416d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 196516d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 196616d9e3a6SLisandro Dalcin jac->cycletype = 1; 196716d9e3a6SLisandro Dalcin jac->maxlevels = 25; 196816d9e3a6SLisandro Dalcin jac->maxiter = 1; 19698f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 197016d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 197116d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 197216d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 197316d9e3a6SLisandro Dalcin jac->coarsentype = 6; 197416d9e3a6SLisandro Dalcin jac->measuretype = 0; 19750f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 19766a251517SEike Mueller jac->smoothtype = -1; /* Not set by default */ 1977b9eb5777SEike Mueller jac->smoothnumlevels = 25; 19781810e44eSEike Mueller jac->eu_level = 0; 19791810e44eSEike Mueller jac->eu_droptolerance = 0; 19801810e44eSEike Mueller jac->eu_bj = 0; 1981589dcaf0SStefano Zampini jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */ 19820f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 198316d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 198416d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 198516d9e3a6SLisandro Dalcin jac->relaxorder = 1; 19860f1074feSSatish Balay jac->interptype = 0; 1987589dcaf0SStefano Zampini jac->Rtype = 0; 1988589dcaf0SStefano Zampini jac->Rstrongthreshold = 0.25; 1989589dcaf0SStefano Zampini jac->Rfilterthreshold = 0.0; 1990589dcaf0SStefano Zampini jac->Adroptype = -1; 1991589dcaf0SStefano Zampini jac->Adroptol = 0.0; 19920f1074feSSatish Balay jac->agg_nl = 0; 19936ea7df73SStefano Zampini jac->agg_interptype = 4; 19940f1074feSSatish Balay jac->pmax = 0; 19950f1074feSSatish Balay jac->truncfactor = 0.0; 19960f1074feSSatish Balay jac->agg_num_paths = 1; 1997589dcaf0SStefano Zampini jac->maxc = 9; 1998589dcaf0SStefano Zampini jac->minc = 1; 199922e51d31SStefano Zampini jac->nodal_coarsening = 0; 200022e51d31SStefano Zampini jac->nodal_coarsening_diag = 0; 200122e51d31SStefano Zampini jac->vec_interp_variant = 0; 200222e51d31SStefano Zampini jac->vec_interp_qmax = 0; 200322e51d31SStefano Zampini jac->vec_interp_smooth = PETSC_FALSE; 200422e51d31SStefano Zampini jac->interp_refine = 0; 20058f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 20068f87f92bSBarry Smith jac->nodal_relax_levels = 1; 20076ea7df73SStefano Zampini jac->rap2 = 0; 20086ea7df73SStefano Zampini 20096ea7df73SStefano Zampini /* GPU defaults 20106ea7df73SStefano Zampini from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options 20116ea7df73SStefano Zampini and /src/parcsr_ls/par_amg.c */ 20126ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 20136ea7df73SStefano Zampini jac->keeptranspose = PETSC_TRUE; 20146ea7df73SStefano Zampini jac->mod_rap2 = 1; 20156ea7df73SStefano Zampini jac->coarsentype = 8; 20166ea7df73SStefano Zampini jac->relaxorder = 0; 20176ea7df73SStefano Zampini jac->interptype = 6; 20186ea7df73SStefano Zampini jac->relaxtype[0] = 18; 20196ea7df73SStefano Zampini jac->relaxtype[1] = 18; 20206ea7df73SStefano Zampini jac->agg_interptype = 7; 20216ea7df73SStefano Zampini #else 20226ea7df73SStefano Zampini jac->keeptranspose = PETSC_FALSE; 20236ea7df73SStefano Zampini jac->mod_rap2 = 0; 20246ea7df73SStefano Zampini #endif 2025792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 2026792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 2027792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 2028792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 2029792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 2030792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 2031792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 2032792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 2033792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 2034792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 2035792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 2036792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 2037792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggInterpType, jac->hsolver, jac->agg_interptype); 2038792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 2039792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 2040792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, jac->relaxtype[0]); /* defaults coarse to 9 */ 2041792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps, jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */ 2042792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 2043792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 20446ea7df73SStefano Zampini /* GPU */ 20456ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 2046792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 2047792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRAP2, jac->hsolver, jac->rap2); 2048792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetModuleRAP2, jac->hsolver, jac->mod_rap2); 20496ea7df73SStefano Zampini #endif 20506ea7df73SStefano Zampini 2051589dcaf0SStefano Zampini /* AIR */ 20526ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 2053792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 2054792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 2055792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 2056792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 2057792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 20586ea7df73SStefano Zampini #endif 20593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 206016d9e3a6SLisandro Dalcin } 20619566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ams", jac->hypre_type, &flag)); 20624cb006feSStefano Zampini if (flag) { 20633ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_AMSCreate, &jac->hsolver); 20644cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 20654cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 20664cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 20674cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 20684cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 20694cb006feSStefano Zampini jac->coords[0] = NULL; 20704cb006feSStefano Zampini jac->coords[1] = NULL; 20714cb006feSStefano Zampini jac->coords[2] = NULL; 2072be14dc20SKerry Key jac->interior = NULL; 20734cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 2074863406b8SStefano Zampini jac->as_print = 0; 2075863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2076863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 20774cb006feSStefano Zampini jac->ams_cycle_type = 13; 20784cb006feSStefano Zampini /* Smoothing options */ 2079863406b8SStefano Zampini jac->as_relax_type = 2; 2080863406b8SStefano Zampini jac->as_relax_times = 1; 2081863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2082863406b8SStefano Zampini jac->as_omega = 1.0; 20834cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2084863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2085863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 20860bdd8552SBarry Smith jac->as_amg_alpha_opts[2] = 6; 2087863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2088863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2089863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 20904cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2091863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2092863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 20930bdd8552SBarry Smith jac->as_amg_beta_opts[2] = 6; 2094863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2095863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2096863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2097792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 2098792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 2099792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2100792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 21019371c9d4SSatish Balay PetscCallExternal(HYPRE_AMSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2102792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2103863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2104863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 21059371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2106a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2107792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2108863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2109863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 21109371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2111a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 211223df4f25SStefano Zampini /* Zero conductivity */ 211323df4f25SStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 211423df4f25SStefano Zampini jac->ams_beta_is_zero_part = PETSC_FALSE; 21153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21164cb006feSStefano Zampini } 21179566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ads", jac->hypre_type, &flag)); 2118863406b8SStefano Zampini if (flag) { 21193ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_ADSCreate, &jac->hsolver); 2120863406b8SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ADS; 2121863406b8SStefano Zampini pc->ops->view = PCView_HYPRE_ADS; 2122863406b8SStefano Zampini jac->destroy = HYPRE_ADSDestroy; 2123863406b8SStefano Zampini jac->setup = HYPRE_ADSSetup; 2124863406b8SStefano Zampini jac->solve = HYPRE_ADSSolve; 2125863406b8SStefano Zampini jac->coords[0] = NULL; 2126863406b8SStefano Zampini jac->coords[1] = NULL; 2127863406b8SStefano Zampini jac->coords[2] = NULL; 2128863406b8SStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */ 2129863406b8SStefano Zampini jac->as_print = 0; 2130863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2131863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 2132863406b8SStefano Zampini jac->ads_cycle_type = 13; 2133863406b8SStefano Zampini /* Smoothing options */ 2134863406b8SStefano Zampini jac->as_relax_type = 2; 2135863406b8SStefano Zampini jac->as_relax_times = 1; 2136863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2137863406b8SStefano Zampini jac->as_omega = 1.0; 2138863406b8SStefano Zampini /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2139863406b8SStefano Zampini jac->ams_cycle_type = 14; 2140863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2141863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 2142863406b8SStefano Zampini jac->as_amg_alpha_opts[2] = 6; 2143863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2144863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2145863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 2146863406b8SStefano Zampini /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2147863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2148863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 2149863406b8SStefano Zampini jac->as_amg_beta_opts[2] = 6; 2150863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2151863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2152863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2153792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 2154792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 2155792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2156792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 21579371c9d4SSatish Balay PetscCallExternal(HYPRE_ADSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2158792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMG coarsen type */ 2159863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2160863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2161863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 21629371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2163a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2164792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2165863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2166863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 21679371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2168a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 21693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2170863406b8SStefano Zampini } 21719566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 21722fa5cd67SKarl Rupp 21730298fd71SBarry Smith jac->hypre_type = NULL; 217498921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams", name); 217516d9e3a6SLisandro Dalcin } 217616d9e3a6SLisandro Dalcin 217716d9e3a6SLisandro Dalcin /* 217816d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 217916d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 218016d9e3a6SLisandro Dalcin */ 2181ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE(PC pc, PetscOptionItems *PetscOptionsObject) 2182d71ae5a4SJacob Faibussowitsch { 21834ddd07fcSJed Brown PetscInt indx; 2184db966c6cSHong Zhang const char *type[] = {"euclid", "pilut", "parasails", "boomeramg", "ams", "ads"}; 2185ace3abfcSBarry Smith PetscBool flg; 218616d9e3a6SLisandro Dalcin 218716d9e3a6SLisandro Dalcin PetscFunctionBegin; 2188d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE preconditioner options"); 2189dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_type", "HYPRE preconditioner type", "PCHYPRESetType", type, PETSC_STATIC_ARRAY_LENGTH(type), "boomeramg", &indx, &flg)); 219016d9e3a6SLisandro Dalcin if (flg) { 21919566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc, type[indx])); 219202a17cd4SBarry Smith } else { 21939566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc, "boomeramg")); 219416d9e3a6SLisandro Dalcin } 2195dbbe0bcdSBarry Smith PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject); 2196d0609cedSBarry Smith PetscOptionsHeadEnd(); 21973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 219816d9e3a6SLisandro Dalcin } 219916d9e3a6SLisandro Dalcin 220016d9e3a6SLisandro Dalcin /*@C 220116d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 220216d9e3a6SLisandro Dalcin 220316d9e3a6SLisandro Dalcin Input Parameters: 220416d9e3a6SLisandro Dalcin + pc - the preconditioner context 2205db966c6cSHong Zhang - name - either euclid, pilut, parasails, boomeramg, ams, ads 220616d9e3a6SLisandro Dalcin 2207f1580f4eSBarry Smith Options Database Key: 2208feefa0e1SJacob Faibussowitsch . pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 220916d9e3a6SLisandro Dalcin 221016d9e3a6SLisandro Dalcin Level: intermediate 221116d9e3a6SLisandro Dalcin 2212562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRE` 221316d9e3a6SLisandro Dalcin @*/ 2214d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetType(PC pc, const char name[]) 2215d71ae5a4SJacob Faibussowitsch { 221616d9e3a6SLisandro Dalcin PetscFunctionBegin; 22170700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 22184f572ea9SToby Isaac PetscAssertPointer(name, 2); 2219cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetType_C", (PC, const char[]), (pc, name)); 22203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 222116d9e3a6SLisandro Dalcin } 222216d9e3a6SLisandro Dalcin 222316d9e3a6SLisandro Dalcin /*@C 222416d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 222516d9e3a6SLisandro Dalcin 222616d9e3a6SLisandro Dalcin Input Parameter: 222716d9e3a6SLisandro Dalcin . pc - the preconditioner context 222816d9e3a6SLisandro Dalcin 222916d9e3a6SLisandro Dalcin Output Parameter: 2230db966c6cSHong Zhang . name - either euclid, pilut, parasails, boomeramg, ams, ads 223116d9e3a6SLisandro Dalcin 223216d9e3a6SLisandro Dalcin Level: intermediate 223316d9e3a6SLisandro Dalcin 2234562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`, `PCHYPRE` 223516d9e3a6SLisandro Dalcin @*/ 2236d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREGetType(PC pc, const char *name[]) 2237d71ae5a4SJacob Faibussowitsch { 223816d9e3a6SLisandro Dalcin PetscFunctionBegin; 22390700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 22404f572ea9SToby Isaac PetscAssertPointer(name, 2); 2241cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPREGetType_C", (PC, const char *[]), (pc, name)); 22423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 224316d9e3a6SLisandro Dalcin } 224416d9e3a6SLisandro Dalcin 2245db6f9c32SMark Adams /*@C 2246f1580f4eSBarry Smith PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use on GPUs 2247db6f9c32SMark Adams 2248c3339decSBarry Smith Logically Collective 2249db6f9c32SMark Adams 2250db6f9c32SMark Adams Input Parameters: 2251db6f9c32SMark Adams + pc - the hypre context 2252feefa0e1SJacob Faibussowitsch - name - one of 'cusparse', 'hypre' 2253db6f9c32SMark Adams 2254db6f9c32SMark Adams Options Database Key: 225567b8a455SSatish Balay . -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre 2256db6f9c32SMark Adams 2257db6f9c32SMark Adams Level: intermediate 2258db6f9c32SMark Adams 2259feefa0e1SJacob Faibussowitsch Developer Notes: 2260f1580f4eSBarry Smith How the name starts with `PCMG`, should it not be `PCHYPREBoomerAMG`? 2261db6f9c32SMark Adams 2262562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinGetMatProductAlgorithm()` 2263db6f9c32SMark Adams @*/ 2264d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc, const char name[]) 2265d71ae5a4SJacob Faibussowitsch { 2266db6f9c32SMark Adams PetscFunctionBegin; 2267db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2268cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinSetMatProductAlgorithm_C", (PC, const char[]), (pc, name)); 22693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2270db6f9c32SMark Adams } 2271db6f9c32SMark Adams 2272db6f9c32SMark Adams /*@C 2273f1580f4eSBarry Smith PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre to use on GPUs 2274db6f9c32SMark Adams 2275db6f9c32SMark Adams Not Collective 2276db6f9c32SMark Adams 2277db6f9c32SMark Adams Input Parameter: 2278db6f9c32SMark Adams . pc - the multigrid context 2279db6f9c32SMark Adams 2280db6f9c32SMark Adams Output Parameter: 2281db6f9c32SMark Adams . name - one of 'cusparse', 'hypre' 2282db6f9c32SMark Adams 2283db6f9c32SMark Adams Level: intermediate 2284db6f9c32SMark Adams 2285562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, ``PCMGGalerkinSetMatProductAlgorithm()` 2286db6f9c32SMark Adams @*/ 2287d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc, const char *name[]) 2288d71ae5a4SJacob Faibussowitsch { 2289db6f9c32SMark Adams PetscFunctionBegin; 2290db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2291cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinGetMatProductAlgorithm_C", (PC, const char *[]), (pc, name)); 22923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2293db6f9c32SMark Adams } 2294db6f9c32SMark Adams 229516d9e3a6SLisandro Dalcin /*MC 2296f1580f4eSBarry Smith PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre as PETSc `PC` 229716d9e3a6SLisandro Dalcin 229816d9e3a6SLisandro Dalcin Options Database Keys: 2299e1ded407SBarry Smith + -pc_hypre_type - One of `euclid`, `pilut`, `parasails`, `boomeramg`, `ams`, or `ads` 2300f1580f4eSBarry Smith . -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see `HYPRE_BOOMERAMGSetNodal()`) 2301f1580f4eSBarry Smith . -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see `HYPRE_BoomerAMGSetInterpVecVariant()`) 2302e1ded407SBarry Smith - Many others, run with `-pc_type hypre` `-pc_hypre_type XXX` `-help` to see options for the XXX preconditioner 230316d9e3a6SLisandro Dalcin 230416d9e3a6SLisandro Dalcin Level: intermediate 230516d9e3a6SLisandro Dalcin 230695452b02SPatrick Sanan Notes: 2307e1ded407SBarry Smith Apart from `-pc_hypre_type` (for which there is `PCHYPRESetType()`), 230816d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 230949567fc5SPierre Jolivet or with `PetscOptionsSetValue()`, there are no functions to set them) 231016d9e3a6SLisandro Dalcin 2311e1ded407SBarry Smith The options `-pc_hypre_boomeramg_max_iter` and `-pc_hypre_boomeramg_tol` refer to the number of iterations 2312e1ded407SBarry Smith (V-cycles) and tolerance that boomerAMG does EACH time it is called. So for example, if 2313e1ded407SBarry Smith `-pc_hypre_boomeramg_max_iter` is set to 2 then 2-V-cycles are being used to define the preconditioner 2314e1ded407SBarry Smith (`-pc_hypre_boomeramg_tol` should be set to 0.0 - the default - to strictly use a fixed number of 2315e1ded407SBarry Smith iterations per hypre call). `-ksp_max_it` and `-ksp_rtol` STILL determine the total number of iterations 2316e1ded407SBarry Smith and tolerance for the Krylov solver. For example, if `-pc_hypre_boomeramg_max_iter` is 2 and `-ksp_max_it` is 10 2317e1ded407SBarry Smith then AT MOST twenty V-cycles of boomeramg will be used. 231816d9e3a6SLisandro Dalcin 2319e1ded407SBarry Smith Note that the option `-pc_hypre_boomeramg_relax_type_all` defaults to symmetric relaxation 23200f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 2321e1ded407SBarry Smith Otherwise, you may want to use `-pc_hypre_boomeramg_relax_type_all SOR/Jacobi`. 232216d9e3a6SLisandro Dalcin 2323f1580f4eSBarry Smith `MatSetNearNullSpace()` - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use 2324e1ded407SBarry Smith the following two options: `-pc_hypre_boomeramg_nodal_coarsen <n> -pc_hypre_boomeramg_vec_interp_variant <v>` 23250b1a5bd9SEric Chamberland 2326f1580f4eSBarry Smith See `PCPFMG`, `PCSMG`, and `PCSYSPFMG` for access to hypre's other (nonalgebraic) multigrid solvers 2327f1580f4eSBarry Smith 2328e1ded407SBarry Smith For `PCHYPRE` type of `ams` or `ads` auxiliary data must be provided to the preconditioner with `PCHYPRESetDiscreteGradient()`, 2329f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 233049567fc5SPierre Jolivet `PCHYPREAMSSetInteriorNodes()` 2331f1580f4eSBarry Smith 2332e1ded407SBarry 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 2333e1ded407SBarry Smith since it is usually slower, one should use a `KSPType` of `KSPRICHARDSON` 2334e1ded407SBarry Smith (or equivalently `-ksp_type richardson`) to achieve this. Using `KSPPREONLY` will not work since it only applies a single cycle of multigrid. 2335e1ded407SBarry Smith 2336f1580f4eSBarry Smith PETSc provides its own geometric and algebraic multigrid solvers `PCMG` and `PCGAMG`, also see `PCHMG` which is useful for certain multicomponent problems 23379e5bc791SBarry Smith 2338ead8c081SBarry Smith GPU Notes: 2339ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda 2340f1580f4eSBarry Smith Then pass `VECCUDA` vectors and `MATAIJCUSPARSE` matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2341ead8c081SBarry Smith 2342ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip 2343f1580f4eSBarry Smith Then pass `VECHIP` vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2344ead8c081SBarry Smith 2345562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRESetType()`, `PCPFMG`, `PCGAMG`, `PCSYSPFMG`, `PCSMG`, `PCHYPRESetDiscreteGradient()`, 2346f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 2347f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes() 234816d9e3a6SLisandro Dalcin M*/ 234916d9e3a6SLisandro Dalcin 2350d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 2351d71ae5a4SJacob Faibussowitsch { 235216d9e3a6SLisandro Dalcin PC_HYPRE *jac; 235316d9e3a6SLisandro Dalcin 235416d9e3a6SLisandro Dalcin PetscFunctionBegin; 23554dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac)); 23562fa5cd67SKarl Rupp 235716d9e3a6SLisandro Dalcin pc->data = jac; 23588695de01SBarry Smith pc->ops->reset = PCReset_HYPRE; 235916d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 236016d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 236116d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 236216d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 236316d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 23649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", PCHYPRESetType_HYPRE)); 23659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", PCHYPREGetType_HYPRE)); 23669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", PCSetCoordinates_HYPRE)); 23679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", PCHYPRESetDiscreteGradient_HYPRE)); 23689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", PCHYPRESetDiscreteCurl_HYPRE)); 23699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", PCHYPRESetInterpolations_HYPRE)); 23709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", PCHYPRESetEdgeConstantVectors_HYPRE)); 2371be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", PCHYPREAMSSetInteriorNodes_HYPRE)); 23729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", PCHYPRESetPoissonMatrix_HYPRE)); 23739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG)); 23749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG)); 23756ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 23766ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 23779566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 23786ea7df73SStefano Zampini #endif 23796ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 23809566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 23816ea7df73SStefano Zampini #endif 23826ea7df73SStefano Zampini #endif 2383ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 23843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 238516d9e3a6SLisandro Dalcin } 2386ebc551c0SBarry Smith 2387ebc551c0SBarry Smith typedef struct { 238868326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 2389f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 23909e5bc791SBarry Smith 23919e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 23924ddd07fcSJed Brown PetscInt its; 23939e5bc791SBarry Smith double tol; 23944ddd07fcSJed Brown PetscInt relax_type; 23954ddd07fcSJed Brown PetscInt rap_type; 23964ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 23974ddd07fcSJed Brown PetscInt max_levels; 23980be8cd64Sftrigaux PetscInt skip_relax; 23990be8cd64Sftrigaux PetscBool print_statistics; 2400ebc551c0SBarry Smith } PC_PFMG; 2401ebc551c0SBarry Smith 2402ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_PFMG(PC pc) 2403d71ae5a4SJacob Faibussowitsch { 2404f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2405ebc551c0SBarry Smith 2406ebc551c0SBarry Smith PetscFunctionBegin; 2407792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 24089566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 24099566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 24103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2411ebc551c0SBarry Smith } 2412ebc551c0SBarry Smith 24139e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi", "Weighted-Jacobi", "symmetric-Red/Black-Gauss-Seidel", "Red/Black-Gauss-Seidel"}; 24149e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin", "non-Galerkin"}; 24159e5bc791SBarry Smith 2416ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_PFMG(PC pc, PetscViewer viewer) 2417d71ae5a4SJacob Faibussowitsch { 2418ace3abfcSBarry Smith PetscBool iascii; 2419f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2420ebc551c0SBarry Smith 2421ebc551c0SBarry Smith PetscFunctionBegin; 24229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 24239e5bc791SBarry Smith if (iascii) { 24249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE PFMG preconditioning\n")); 242563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 24269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 24279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 24289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " RAP type %s\n", PFMGRAPType[ex->rap_type])); 242963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 243063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max levels %" PetscInt_FMT "\n", ex->max_levels)); 24310be8cd64Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " skip relax %" PetscInt_FMT "\n", ex->skip_relax)); 24329e5bc791SBarry Smith } 24333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2434ebc551c0SBarry Smith } 2435ebc551c0SBarry Smith 2436ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_PFMG(PC pc, PetscOptionItems *PetscOptionsObject) 2437d71ae5a4SJacob Faibussowitsch { 2438f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2439ebc551c0SBarry Smith 2440ebc551c0SBarry Smith PetscFunctionBegin; 2441d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PFMG options"); 24420be8cd64Sftrigaux PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics", "Print statistics", "HYPRE_StructPFMGSetPrintLevel", ex->print_statistics, &ex->print_statistics, NULL)); 24439566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_its", "Number of iterations of PFMG to use as preconditioner", "HYPRE_StructPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2444792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 24459566063dSJacob 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)); 2446792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 24479566063dSJacob 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)); 2448792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 24499e5bc791SBarry Smith 24509566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_max_levels", "Max Levels for MG hierarchy", "HYPRE_StructPFMGSetMaxLevels", ex->max_levels, &ex->max_levels, NULL)); 2451792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 24523b46a515SGlenn Hammond 24539566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_pfmg_tol", "Tolerance of PFMG", "HYPRE_StructPFMGSetTol", ex->tol, &ex->tol, NULL)); 2454792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 2455dd39110bSPierre 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)); 2456792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 2457dd39110bSPierre 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)); 2458792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 24590be8cd64Sftrigaux 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)); 24600be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetSkipRelax, ex->hsolver, ex->skip_relax); 2461d0609cedSBarry Smith PetscOptionsHeadEnd(); 24623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2463ebc551c0SBarry Smith } 2464ebc551c0SBarry Smith 2465ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_PFMG(PC pc, Vec x, Vec y) 2466d71ae5a4SJacob Faibussowitsch { 2467f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2468d9ca1df4SBarry Smith PetscScalar *yy; 2469d9ca1df4SBarry Smith const PetscScalar *xx; 24704ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 24712cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 247268326731SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 2473f91d8e95SBarry Smith 2474f91d8e95SBarry Smith PetscFunctionBegin; 24759566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 24769566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 24772cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2478f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 2479f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 2480f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 24812cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 24822cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 24832cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 24842cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 24852cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 24862cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2487f91d8e95SBarry Smith 2488f91d8e95SBarry Smith /* copy x values over to hypre */ 2489792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 24909566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2491792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 24929566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2493792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 2494792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2495f91d8e95SBarry Smith 2496f91d8e95SBarry Smith /* copy solution values back to PETSc */ 24979566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2498792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 24999566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 25003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2501f91d8e95SBarry Smith } 2502f91d8e95SBarry Smith 2503d71ae5a4SJacob 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) 2504d71ae5a4SJacob Faibussowitsch { 25059e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG *)pc->data; 25062cf14000SStefano Zampini HYPRE_Int oits; 25079e5bc791SBarry Smith 25089e5bc791SBarry Smith PetscFunctionBegin; 25099566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 2510792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, its * jac->its); 2511792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, rtol); 25129e5bc791SBarry Smith 25139566063dSJacob Faibussowitsch PetscCall(PCApply_PFMG(pc, b, y)); 2514792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGGetNumIterations, jac->hsolver, &oits); 25159e5bc791SBarry Smith *outits = oits; 25169e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 25179e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 2518792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, jac->tol); 2519792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, jac->its); 25203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25219e5bc791SBarry Smith } 25229e5bc791SBarry Smith 2523ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_PFMG(PC pc) 2524d71ae5a4SJacob Faibussowitsch { 25253a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG *)pc->data; 25263a32d3dbSGlenn Hammond Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 2527ace3abfcSBarry Smith PetscBool flg; 25283a32d3dbSGlenn Hammond 25293a32d3dbSGlenn Hammond PetscFunctionBegin; 25309566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 253128b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 25323a32d3dbSGlenn Hammond 25333a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 2534792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 2535792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 25360be8cd64Sftrigaux 25370be8cd64Sftrigaux // Print Hypre statistics about the solve process 25380be8cd64Sftrigaux if (ex->print_statistics) PetscCallExternal(HYPRE_StructPFMGSetPrintLevel, ex->hsolver, 3); 25390be8cd64Sftrigaux 25400be8cd64Sftrigaux // The hypre options must be repeated here because the StructPFMG was destroyed and recreated 25410be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 25420be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 25430be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 25440be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 25450be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 25460be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 25470be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 25480be8cd64Sftrigaux 2549792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2550792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetZeroGuess, ex->hsolver); 25513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25523a32d3dbSGlenn Hammond } 25533a32d3dbSGlenn Hammond 2554ebc551c0SBarry Smith /*MC 2555ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 2556ebc551c0SBarry Smith 2557f1580f4eSBarry Smith Options Database Keys: 255867b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner 255967b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve 256067b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve 256167b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG 25629e5bc791SBarry 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 25630be8cd64Sftrigaux . -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 2564f1580f4eSBarry Smith - -pc_pfmg_skip_relax - skip relaxation on certain grids for isotropic problems. This can greatly improve efficiency by eliminating unnecessary relaxations 2565f1580f4eSBarry Smith when the underlying problem is isotropic, one of 0,1 2566f1580f4eSBarry Smith 2567f1580f4eSBarry Smith Level: advanced 2568f91d8e95SBarry Smith 256995452b02SPatrick Sanan Notes: 257095452b02SPatrick Sanan This is for CELL-centered descretizations 25719e5bc791SBarry Smith 2572f1580f4eSBarry Smith See `PCSYSPFMG` for a version suitable for systems of PDEs, and `PCSMG` 25739e5bc791SBarry Smith 2574f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 2575f1580f4eSBarry Smith 2576f1580f4eSBarry Smith This must be used with the `MATHYPRESTRUCT` matrix type. 2577f1580f4eSBarry Smith 2578f1580f4eSBarry Smith This provides only some of the functionality of PFMG, it supports only one block per process defined by a PETSc `DMDA`. 2579f1580f4eSBarry Smith 2580562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESTRUCT`, `PCHYPRE`, `PCGAMG`, `PCSYSPFMG`, `PCSMG` 2581ebc551c0SBarry Smith M*/ 2582ebc551c0SBarry Smith 2583d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 2584d71ae5a4SJacob Faibussowitsch { 2585ebc551c0SBarry Smith PC_PFMG *ex; 2586ebc551c0SBarry Smith 2587ebc551c0SBarry Smith PetscFunctionBegin; 25889371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 258968326731SBarry Smith pc->data = ex; 2590ebc551c0SBarry Smith 25919e5bc791SBarry Smith ex->its = 1; 25929e5bc791SBarry Smith ex->tol = 1.e-8; 25939e5bc791SBarry Smith ex->relax_type = 1; 25949e5bc791SBarry Smith ex->rap_type = 0; 25959e5bc791SBarry Smith ex->num_pre_relax = 1; 25969e5bc791SBarry Smith ex->num_post_relax = 1; 25973b46a515SGlenn Hammond ex->max_levels = 0; 25980be8cd64Sftrigaux ex->skip_relax = 0; 25990be8cd64Sftrigaux ex->print_statistics = PETSC_FALSE; 26009e5bc791SBarry Smith 2601ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 2602ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 2603ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 2604f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 26059e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 260668326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 26072fa5cd67SKarl Rupp 26089566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 2609ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 2610792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 26113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2612ebc551c0SBarry Smith } 2613d851a50bSGlenn Hammond 2614d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 2615d851a50bSGlenn Hammond typedef struct { 2616d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 2617d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 2618d851a50bSGlenn Hammond 2619d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 26204ddd07fcSJed Brown PetscInt its; 2621d851a50bSGlenn Hammond double tol; 26224ddd07fcSJed Brown PetscInt relax_type; 26234ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 2624d851a50bSGlenn Hammond } PC_SysPFMG; 2625d851a50bSGlenn Hammond 2626ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SysPFMG(PC pc) 2627d71ae5a4SJacob Faibussowitsch { 2628d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2629d851a50bSGlenn Hammond 2630d851a50bSGlenn Hammond PetscFunctionBegin; 2631792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 26329566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 26339566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 26343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2635d851a50bSGlenn Hammond } 2636d851a50bSGlenn Hammond 2637d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi", "Red/Black-Gauss-Seidel"}; 2638d851a50bSGlenn Hammond 2639ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SysPFMG(PC pc, PetscViewer viewer) 2640d71ae5a4SJacob Faibussowitsch { 2641ace3abfcSBarry Smith PetscBool iascii; 2642d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2643d851a50bSGlenn Hammond 2644d851a50bSGlenn Hammond PetscFunctionBegin; 26459566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 2646d851a50bSGlenn Hammond if (iascii) { 26479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SysPFMG preconditioning\n")); 264863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 26499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 26509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 265163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 2652d851a50bSGlenn Hammond } 26533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2654d851a50bSGlenn Hammond } 2655d851a50bSGlenn Hammond 2656ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_SysPFMG(PC pc, PetscOptionItems *PetscOptionsObject) 2657d71ae5a4SJacob Faibussowitsch { 2658d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2659ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2660d851a50bSGlenn Hammond 2661d851a50bSGlenn Hammond PetscFunctionBegin; 2662d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SysPFMG options"); 26639566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics", "Print statistics", "HYPRE_SStructSysPFMGSetPrintLevel", flg, &flg, NULL)); 266448a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_SStructSysPFMGSetPrintLevel, ex->ss_solver, 3); 26659566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_its", "Number of iterations of SysPFMG to use as preconditioner", "HYPRE_SStructSysPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2666792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, ex->ss_solver, ex->its); 26679566063dSJacob 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)); 2668792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPreRelax, ex->ss_solver, ex->num_pre_relax); 26699566063dSJacob 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)); 2670792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPostRelax, ex->ss_solver, ex->num_post_relax); 2671d851a50bSGlenn Hammond 26729566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_syspfmg_tol", "Tolerance of SysPFMG", "HYPRE_SStructSysPFMGSetTol", ex->tol, &ex->tol, NULL)); 2673792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, ex->ss_solver, ex->tol); 2674dd39110bSPierre 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)); 2675792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetRelaxType, ex->ss_solver, ex->relax_type); 2676d0609cedSBarry Smith PetscOptionsHeadEnd(); 26773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2678d851a50bSGlenn Hammond } 2679d851a50bSGlenn Hammond 2680ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SysPFMG(PC pc, Vec x, Vec y) 2681d71ae5a4SJacob Faibussowitsch { 2682d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2683d9ca1df4SBarry Smith PetscScalar *yy; 2684d9ca1df4SBarry Smith const PetscScalar *xx; 26854ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 26862cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 2687d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)(pc->pmat->data); 26884ddd07fcSJed Brown PetscInt ordering = mx->dofs_order; 26894ddd07fcSJed Brown PetscInt nvars = mx->nvars; 26904ddd07fcSJed Brown PetscInt part = 0; 26914ddd07fcSJed Brown PetscInt size; 26924ddd07fcSJed Brown PetscInt i; 2693d851a50bSGlenn Hammond 2694d851a50bSGlenn Hammond PetscFunctionBegin; 26959566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 26969566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 26972cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2698d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 2699d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 2700d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 27012cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 27022cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 27032cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 27042cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 27052cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 27062cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2707d851a50bSGlenn Hammond 2708d851a50bSGlenn Hammond size = 1; 27092fa5cd67SKarl Rupp for (i = 0; i < 3; i++) size *= (iupper[i] - ilower[i] + 1); 27102fa5cd67SKarl Rupp 2711d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 2712d851a50bSGlenn Hammond if (ordering) { 2713792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 27149566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2715792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(xx + (size * i))); 27169566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2717792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 2718792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructMatrixMatvec, 1.0, mx->ss_mat, mx->ss_b, 0.0, mx->ss_x); 2719792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 2720d851a50bSGlenn Hammond 2721d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 27229566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2723792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(yy + (size * i))); 27249566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 2725a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 2726d851a50bSGlenn Hammond PetscScalar *z; 27274ddd07fcSJed Brown PetscInt j, k; 2728d851a50bSGlenn Hammond 27299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvars * size, &z)); 2730792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 27319566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2732d851a50bSGlenn Hammond 2733d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 2734d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 2735d851a50bSGlenn Hammond k = i * nvars; 27362fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) z[j * size + i] = xx[k + j]; 2737d851a50bSGlenn Hammond } 2738792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 27399566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2740792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 2741792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 2742d851a50bSGlenn Hammond 2743d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 27449566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2745792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 2746d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 2747d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 2748d851a50bSGlenn Hammond k = i * nvars; 27492fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) yy[k + j] = z[j * size + i]; 2750d851a50bSGlenn Hammond } 27519566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 27529566063dSJacob Faibussowitsch PetscCall(PetscFree(z)); 2753d851a50bSGlenn Hammond } 27543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2755d851a50bSGlenn Hammond } 2756d851a50bSGlenn Hammond 2757d71ae5a4SJacob 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) 2758d71ae5a4SJacob Faibussowitsch { 2759d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG *)pc->data; 27602cf14000SStefano Zampini HYPRE_Int oits; 2761d851a50bSGlenn Hammond 2762d851a50bSGlenn Hammond PetscFunctionBegin; 27639566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 2764792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, its * jac->its); 2765792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, rtol); 27669566063dSJacob Faibussowitsch PetscCall(PCApply_SysPFMG(pc, b, y)); 2767792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGGetNumIterations, jac->ss_solver, &oits); 2768d851a50bSGlenn Hammond *outits = oits; 2769d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 2770d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 2771792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, jac->tol); 2772792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, jac->its); 27733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2774d851a50bSGlenn Hammond } 2775d851a50bSGlenn Hammond 2776ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SysPFMG(PC pc) 2777d71ae5a4SJacob Faibussowitsch { 2778d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2779d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)(pc->pmat->data); 2780ace3abfcSBarry Smith PetscBool flg; 2781d851a50bSGlenn Hammond 2782d851a50bSGlenn Hammond PetscFunctionBegin; 27839566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESSTRUCT, &flg)); 278428b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESSTRUCT with this preconditioner"); 2785d851a50bSGlenn Hammond 2786d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 2787792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 2788792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 2789792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetZeroGuess, ex->ss_solver); 2790792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetup, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 27913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2792d851a50bSGlenn Hammond } 2793d851a50bSGlenn Hammond 2794d851a50bSGlenn Hammond /*MC 2795f1580f4eSBarry Smith PCSYSPFMG - the hypre SysPFMG multigrid solver 2796d851a50bSGlenn Hammond 2797d851a50bSGlenn Hammond Level: advanced 2798d851a50bSGlenn Hammond 2799f1580f4eSBarry Smith Options Database Keys: 280067b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner 280167b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid 280267b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid 280367b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG 280467b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles 2805d851a50bSGlenn Hammond 280695452b02SPatrick Sanan Notes: 2807f1580f4eSBarry Smith See `PCPFMG` for hypre's PFMG that works for a scalar PDE and `PCSMG` 2808f1580f4eSBarry Smith 2809f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 2810f1580f4eSBarry Smith 281195452b02SPatrick Sanan This is for CELL-centered descretizations 2812d851a50bSGlenn Hammond 2813f1580f4eSBarry Smith This must be used with the `MATHYPRESSTRUCT` matrix type. 2814d851a50bSGlenn Hammond 2815f1580f4eSBarry 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`. 2816f1580f4eSBarry Smith 2817562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESSTRUCT`, `PCPFMG`, `PCHYPRE`, `PCGAMG`, `PCSMG` 2818d851a50bSGlenn Hammond M*/ 2819d851a50bSGlenn Hammond 2820d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 2821d71ae5a4SJacob Faibussowitsch { 2822d851a50bSGlenn Hammond PC_SysPFMG *ex; 2823d851a50bSGlenn Hammond 2824d851a50bSGlenn Hammond PetscFunctionBegin; 28259371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 2826d851a50bSGlenn Hammond pc->data = ex; 2827d851a50bSGlenn Hammond 2828d851a50bSGlenn Hammond ex->its = 1; 2829d851a50bSGlenn Hammond ex->tol = 1.e-8; 2830d851a50bSGlenn Hammond ex->relax_type = 1; 2831d851a50bSGlenn Hammond ex->num_pre_relax = 1; 2832d851a50bSGlenn Hammond ex->num_post_relax = 1; 2833d851a50bSGlenn Hammond 2834d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 2835d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 2836d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 2837d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 2838d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 2839d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 28402fa5cd67SKarl Rupp 28419566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 2842ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 2843792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 28443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2845d851a50bSGlenn Hammond } 28461c188c59Sftrigaux 2847f1580f4eSBarry Smith /* PC SMG */ 28481c188c59Sftrigaux typedef struct { 28491c188c59Sftrigaux MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 28501c188c59Sftrigaux HYPRE_StructSolver hsolver; 28511c188c59Sftrigaux PetscInt its; /* keep copy of SMG options used so may view them */ 28521c188c59Sftrigaux double tol; 28531c188c59Sftrigaux PetscBool print_statistics; 28541c188c59Sftrigaux PetscInt num_pre_relax, num_post_relax; 28551c188c59Sftrigaux } PC_SMG; 28561c188c59Sftrigaux 2857ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SMG(PC pc) 2858d71ae5a4SJacob Faibussowitsch { 28591c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 28601c188c59Sftrigaux 28611c188c59Sftrigaux PetscFunctionBegin; 28621c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, ex->hsolver); 28631c188c59Sftrigaux PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 28641c188c59Sftrigaux PetscCall(PetscFree(pc->data)); 28653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28661c188c59Sftrigaux } 28671c188c59Sftrigaux 2868ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SMG(PC pc, PetscViewer viewer) 2869d71ae5a4SJacob Faibussowitsch { 28701c188c59Sftrigaux PetscBool iascii; 28711c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 28721c188c59Sftrigaux 28731c188c59Sftrigaux PetscFunctionBegin; 28741c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 28751c188c59Sftrigaux if (iascii) { 28761c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SMG preconditioning\n")); 28771c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 28781c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 28791c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 28801c188c59Sftrigaux } 28813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28821c188c59Sftrigaux } 28831c188c59Sftrigaux 2884ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_SMG(PC pc, PetscOptionItems *PetscOptionsObject) 2885d71ae5a4SJacob Faibussowitsch { 28861c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 28871c188c59Sftrigaux 28881c188c59Sftrigaux PetscFunctionBegin; 28891c188c59Sftrigaux PetscOptionsHeadBegin(PetscOptionsObject, "SMG options"); 28901c188c59Sftrigaux 28911c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_its", "Number of iterations of SMG to use as preconditioner", "HYPRE_StructSMGSetMaxIter", ex->its, &ex->its, NULL)); 28921c188c59Sftrigaux 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)); 28931c188c59Sftrigaux 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)); 28941c188c59Sftrigaux PetscCall(PetscOptionsReal("-pc_smg_tol", "Tolerance of SMG", "HYPRE_StructSMGSetTol", ex->tol, &ex->tol, NULL)); 28951c188c59Sftrigaux 28961c188c59Sftrigaux PetscOptionsHeadEnd(); 28973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28981c188c59Sftrigaux } 28991c188c59Sftrigaux 2900ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SMG(PC pc, Vec x, Vec y) 2901d71ae5a4SJacob Faibussowitsch { 29021c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 29031c188c59Sftrigaux PetscScalar *yy; 29041c188c59Sftrigaux const PetscScalar *xx; 29051c188c59Sftrigaux PetscInt ilower[3], iupper[3]; 29061c188c59Sftrigaux HYPRE_Int hlower[3], hupper[3]; 29071c188c59Sftrigaux Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 29081c188c59Sftrigaux 29091c188c59Sftrigaux PetscFunctionBegin; 29101c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 29111c188c59Sftrigaux PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 29121c188c59Sftrigaux /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 29131c188c59Sftrigaux iupper[0] += ilower[0] - 1; 29141c188c59Sftrigaux iupper[1] += ilower[1] - 1; 29151c188c59Sftrigaux iupper[2] += ilower[2] - 1; 29161c188c59Sftrigaux hlower[0] = (HYPRE_Int)ilower[0]; 29171c188c59Sftrigaux hlower[1] = (HYPRE_Int)ilower[1]; 29181c188c59Sftrigaux hlower[2] = (HYPRE_Int)ilower[2]; 29191c188c59Sftrigaux hupper[0] = (HYPRE_Int)iupper[0]; 29201c188c59Sftrigaux hupper[1] = (HYPRE_Int)iupper[1]; 29211c188c59Sftrigaux hupper[2] = (HYPRE_Int)iupper[2]; 29221c188c59Sftrigaux 29231c188c59Sftrigaux /* copy x values over to hypre */ 29241c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 29251c188c59Sftrigaux PetscCall(VecGetArrayRead(x, &xx)); 29261c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 29271c188c59Sftrigaux PetscCall(VecRestoreArrayRead(x, &xx)); 29281c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 29291c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 29301c188c59Sftrigaux 29311c188c59Sftrigaux /* copy solution values back to PETSc */ 29321c188c59Sftrigaux PetscCall(VecGetArray(y, &yy)); 29331c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 29341c188c59Sftrigaux PetscCall(VecRestoreArray(y, &yy)); 29353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29361c188c59Sftrigaux } 29371c188c59Sftrigaux 2938d71ae5a4SJacob 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) 2939d71ae5a4SJacob Faibussowitsch { 29401c188c59Sftrigaux PC_SMG *jac = (PC_SMG *)pc->data; 29411c188c59Sftrigaux HYPRE_Int oits; 29421c188c59Sftrigaux 29431c188c59Sftrigaux PetscFunctionBegin; 29441c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 29451c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, its * jac->its); 29461c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, rtol); 29471c188c59Sftrigaux 29481c188c59Sftrigaux PetscCall(PCApply_SMG(pc, b, y)); 29491c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGGetNumIterations, jac->hsolver, &oits); 29501c188c59Sftrigaux *outits = oits; 29511c188c59Sftrigaux if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 29521c188c59Sftrigaux else *reason = PCRICHARDSON_CONVERGED_RTOL; 29531c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, jac->tol); 29541c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, jac->its); 29553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29561c188c59Sftrigaux } 29571c188c59Sftrigaux 2958ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SMG(PC pc) 2959d71ae5a4SJacob Faibussowitsch { 29601c188c59Sftrigaux PetscInt i, dim; 29611c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 29621c188c59Sftrigaux Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 29631c188c59Sftrigaux PetscBool flg; 29641c188c59Sftrigaux DMBoundaryType p[3]; 29651c188c59Sftrigaux PetscInt M[3]; 29661c188c59Sftrigaux 29671c188c59Sftrigaux PetscFunctionBegin; 29681c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 29691c188c59Sftrigaux PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 29701c188c59Sftrigaux 29711c188c59Sftrigaux PetscCall(DMDAGetInfo(mx->da, &dim, &M[0], &M[1], &M[2], 0, 0, 0, 0, 0, &p[0], &p[1], &p[2], 0)); 29721c188c59Sftrigaux // Check if power of 2 in periodic directions 29731c188c59Sftrigaux for (i = 0; i < dim; i++) { 29741c188c59Sftrigaux if (((M[i] & (M[i] - 1)) != 0) && (p[i] == DM_BOUNDARY_PERIODIC)) { 29751c188c59Sftrigaux 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]); 29761c188c59Sftrigaux } 29771c188c59Sftrigaux } 29781c188c59Sftrigaux 29791c188c59Sftrigaux /* create the hypre solver object and set its information */ 29801c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, (ex->hsolver)); 29811c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 29821c188c59Sftrigaux // The hypre options must be set here and not in SetFromOptions because it is created here! 29831c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, ex->hsolver, ex->its); 29841c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 29851c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 29861c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, ex->hsolver, ex->tol); 29871c188c59Sftrigaux 29881c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 29891c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetZeroGuess, ex->hsolver); 29903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29911c188c59Sftrigaux } 29921c188c59Sftrigaux 29931c188c59Sftrigaux /*MC 29945cb80ecdSBarry Smith PCSMG - the hypre (structured grid) SMG multigrid solver 29951c188c59Sftrigaux 29961c188c59Sftrigaux Level: advanced 29971c188c59Sftrigaux 2998f1580f4eSBarry Smith Options Database Keys: 29995cb80ecdSBarry Smith + -pc_smg_its <its> - number of iterations of SMG to use as preconditioner 30005cb80ecdSBarry Smith . -pc_smg_num_pre_relax <steps> - number of smoothing steps before coarse grid 30015cb80ecdSBarry Smith . -pc_smg_num_post_relax <steps> - number of smoothing steps after coarse grid 30025cb80ecdSBarry Smith - -pc_smg_tol <tol> - tolerance of SMG 30031c188c59Sftrigaux 30041c188c59Sftrigaux Notes: 30051c188c59Sftrigaux This is for CELL-centered descretizations 30061c188c59Sftrigaux 30075cb80ecdSBarry Smith This must be used with the `MATHYPRESTRUCT` `MatType`. 30081c188c59Sftrigaux 3009f1580f4eSBarry 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`. 3010f1580f4eSBarry Smith 3011f1580f4eSBarry Smith See `PCSYSPFMG`, `PCSMG`, `PCPFMG`, and `PCHYPRE` for access to hypre's other preconditioners 3012f1580f4eSBarry Smith 3013f1580f4eSBarry Smith .seealso: `PCMG`, `MATHYPRESTRUCT`, `PCPFMG`, `PCSYSPFMG`, `PCHYPRE`, `PCGAMG` 30141c188c59Sftrigaux M*/ 30151c188c59Sftrigaux 3016d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SMG(PC pc) 3017d71ae5a4SJacob Faibussowitsch { 30181c188c59Sftrigaux PC_SMG *ex; 30191c188c59Sftrigaux 30201c188c59Sftrigaux PetscFunctionBegin; 30219371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 30221c188c59Sftrigaux pc->data = ex; 30231c188c59Sftrigaux 30241c188c59Sftrigaux ex->its = 1; 30251c188c59Sftrigaux ex->tol = 1.e-8; 30261c188c59Sftrigaux ex->num_pre_relax = 1; 30271c188c59Sftrigaux ex->num_post_relax = 1; 30281c188c59Sftrigaux 30291c188c59Sftrigaux pc->ops->setfromoptions = PCSetFromOptions_SMG; 30301c188c59Sftrigaux pc->ops->view = PCView_SMG; 30311c188c59Sftrigaux pc->ops->destroy = PCDestroy_SMG; 30321c188c59Sftrigaux pc->ops->apply = PCApply_SMG; 30331c188c59Sftrigaux pc->ops->applyrichardson = PCApplyRichardson_SMG; 30341c188c59Sftrigaux pc->ops->setup = PCSetUp_SMG; 30351c188c59Sftrigaux 30361c188c59Sftrigaux PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 3037ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 30381c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 30393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30401c188c59Sftrigaux } 3041