116d9e3a6SLisandro Dalcin /* 216d9e3a6SLisandro Dalcin Provides an interface to the LLNL package hypre 316d9e3a6SLisandro Dalcin */ 40f1074feSSatish Balay 5589dcaf0SStefano Zampini #include <petscpkg_version.h> 6af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/ 749a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */ 849a781f5SStefano Zampini #include <petsc/private/matimpl.h> 96ea7df73SStefano Zampini #include <petsc/private/vecimpl.h> 1058968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h> 1149a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h> 12c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h> 134cb006feSStefano Zampini #include <_hypre_parcsr_ls.h> 148a2c336bSFande Kong #include <petscmathypre.h> 1516d9e3a6SLisandro Dalcin 16a4af0ceeSJacob Faibussowitsch #if defined(PETSC_HAVE_HYPRE_DEVICE) 17a4af0ceeSJacob Faibussowitsch #include <petsc/private/deviceimpl.h> 18a4af0ceeSJacob Faibussowitsch #endif 19a4af0ceeSJacob Faibussowitsch 20dff31646SBarry Smith static PetscBool cite = PETSC_FALSE; 219371c9d4SSatish Balay static const char hypreCitation[] = "@manual{hypre-web-page,\n title = {{\\sl hypre}: High Performance Preconditioners},\n organization = {Lawrence Livermore National Laboratory},\n note = " 22bd87328aSJed Brown "{\\url{https://www.llnl.gov/casc/hypre}}\n}\n"; 231f817a21SBarry Smith 2416d9e3a6SLisandro Dalcin /* 2516d9e3a6SLisandro Dalcin Private context (data structure) for the preconditioner. 2616d9e3a6SLisandro Dalcin */ 2716d9e3a6SLisandro Dalcin typedef struct { 2816d9e3a6SLisandro Dalcin HYPRE_Solver hsolver; 2949a781f5SStefano Zampini Mat hpmat; /* MatHYPRE */ 3016d9e3a6SLisandro Dalcin 314ddd07fcSJed Brown HYPRE_Int (*destroy)(HYPRE_Solver); 324ddd07fcSJed Brown HYPRE_Int (*solve)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector); 334ddd07fcSJed Brown HYPRE_Int (*setup)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector); 3416d9e3a6SLisandro Dalcin 3516d9e3a6SLisandro Dalcin MPI_Comm comm_hypre; 3616d9e3a6SLisandro Dalcin char *hypre_type; 3716d9e3a6SLisandro Dalcin 3816d9e3a6SLisandro Dalcin /* options for Pilut and BoomerAMG*/ 394ddd07fcSJed Brown PetscInt maxiter; 4039accc25SStefano Zampini PetscReal tol; 4116d9e3a6SLisandro Dalcin 4216d9e3a6SLisandro Dalcin /* options for Pilut */ 434ddd07fcSJed Brown PetscInt factorrowsize; 4416d9e3a6SLisandro Dalcin 4516d9e3a6SLisandro Dalcin /* options for ParaSails */ 464ddd07fcSJed Brown PetscInt nlevels; 478966356dSPierre Jolivet PetscReal threshold; 4839accc25SStefano Zampini PetscReal filter; 4939accc25SStefano Zampini PetscReal loadbal; 504ddd07fcSJed Brown PetscInt logging; 514ddd07fcSJed Brown PetscInt ruse; 524ddd07fcSJed Brown PetscInt symt; 5316d9e3a6SLisandro Dalcin 5422b6d1caSBarry Smith /* options for BoomerAMG */ 55ace3abfcSBarry Smith PetscBool printstatistics; 5616d9e3a6SLisandro Dalcin 5716d9e3a6SLisandro Dalcin /* options for BoomerAMG */ 584ddd07fcSJed Brown PetscInt cycletype; 594ddd07fcSJed Brown PetscInt maxlevels; 6039accc25SStefano Zampini PetscReal strongthreshold; 6139accc25SStefano Zampini PetscReal maxrowsum; 624ddd07fcSJed Brown PetscInt gridsweeps[3]; 634ddd07fcSJed Brown PetscInt coarsentype; 644ddd07fcSJed Brown PetscInt measuretype; 656a251517SEike Mueller PetscInt smoothtype; 663c61a47dSLukas PetscInt smoothsweeps; 678131ecf7SEike Mueller PetscInt smoothnumlevels; 68ec64516dSEike Mueller PetscInt eu_level; /* Number of levels for ILU(k) in Euclid */ 6939accc25SStefano Zampini PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */ 70ec64516dSEike Mueller PetscInt eu_bj; /* Defines use of Block Jacobi ILU in Euclid */ 714ddd07fcSJed Brown PetscInt relaxtype[3]; 7239accc25SStefano Zampini PetscReal relaxweight; 7339accc25SStefano Zampini PetscReal outerrelaxweight; 744ddd07fcSJed Brown PetscInt relaxorder; 7539accc25SStefano Zampini PetscReal truncfactor; 76ace3abfcSBarry Smith PetscBool applyrichardson; 774ddd07fcSJed Brown PetscInt pmax; 784ddd07fcSJed Brown PetscInt interptype; 79589dcaf0SStefano Zampini PetscInt maxc; 80589dcaf0SStefano Zampini PetscInt minc; 81db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 82db6f9c32SMark Adams char *spgemm_type; // this is a global hypre parameter but is closely associated with BoomerAMG 83db6f9c32SMark Adams #endif 846ea7df73SStefano Zampini /* GPU */ 856ea7df73SStefano Zampini PetscBool keeptranspose; 866ea7df73SStefano Zampini PetscInt rap2; 876ea7df73SStefano Zampini PetscInt mod_rap2; 886ea7df73SStefano Zampini 89589dcaf0SStefano Zampini /* AIR */ 90589dcaf0SStefano Zampini PetscInt Rtype; 91589dcaf0SStefano Zampini PetscReal Rstrongthreshold; 92589dcaf0SStefano Zampini PetscReal Rfilterthreshold; 93589dcaf0SStefano Zampini PetscInt Adroptype; 94589dcaf0SStefano Zampini PetscReal Adroptol; 95589dcaf0SStefano Zampini 964ddd07fcSJed Brown PetscInt agg_nl; 976ea7df73SStefano Zampini PetscInt agg_interptype; 984ddd07fcSJed Brown PetscInt agg_num_paths; 99ace3abfcSBarry Smith PetscBool nodal_relax; 1004ddd07fcSJed Brown PetscInt nodal_relax_levels; 1014cb006feSStefano Zampini 1025272c319SBarry Smith PetscInt nodal_coarsening; 10322e51d31SStefano Zampini PetscInt nodal_coarsening_diag; 1045272c319SBarry Smith PetscInt vec_interp_variant; 10522e51d31SStefano Zampini PetscInt vec_interp_qmax; 10622e51d31SStefano Zampini PetscBool vec_interp_smooth; 10722e51d31SStefano Zampini PetscInt interp_refine; 10822e51d31SStefano Zampini 1096ea7df73SStefano Zampini /* NearNullSpace support */ 1106ea7df73SStefano Zampini VecHYPRE_IJVector *hmnull; 1116ea7df73SStefano Zampini HYPRE_ParVector *phmnull; 1125272c319SBarry Smith PetscInt n_hmnull; 1135272c319SBarry Smith Vec hmnull_constant; 1145272c319SBarry Smith 115863406b8SStefano Zampini /* options for AS (Auxiliary Space preconditioners) */ 116863406b8SStefano Zampini PetscInt as_print; 117863406b8SStefano Zampini PetscInt as_max_iter; 118863406b8SStefano Zampini PetscReal as_tol; 119863406b8SStefano Zampini PetscInt as_relax_type; 120863406b8SStefano Zampini PetscInt as_relax_times; 121863406b8SStefano Zampini PetscReal as_relax_weight; 122863406b8SStefano Zampini PetscReal as_omega; 123863406b8SStefano Zampini PetscInt as_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson (AMS) or Curl problem (ADS) */ 124863406b8SStefano Zampini PetscReal as_amg_alpha_theta; /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */ 125863406b8SStefano Zampini PetscInt as_amg_beta_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson (AMS) or vector Poisson (ADS) */ 126863406b8SStefano Zampini PetscReal as_amg_beta_theta; /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS) */ 1274cb006feSStefano Zampini PetscInt ams_cycle_type; 128863406b8SStefano Zampini PetscInt ads_cycle_type; 1294cb006feSStefano Zampini 1304cb006feSStefano Zampini /* additional data */ 1315ac14e1cSStefano Zampini Mat G; /* MatHYPRE */ 1325ac14e1cSStefano Zampini Mat C; /* MatHYPRE */ 1335ac14e1cSStefano Zampini Mat alpha_Poisson; /* MatHYPRE */ 1345ac14e1cSStefano Zampini Mat beta_Poisson; /* MatHYPRE */ 1355ac14e1cSStefano Zampini 1365ac14e1cSStefano Zampini /* extra information for AMS */ 1375ac14e1cSStefano Zampini PetscInt dim; /* geometrical dimension */ 1386ea7df73SStefano Zampini VecHYPRE_IJVector coords[3]; 1396ea7df73SStefano Zampini VecHYPRE_IJVector constants[3]; 140be14dc20SKerry Key VecHYPRE_IJVector interior; 1416bf688a0SCe Qin Mat RT_PiFull, RT_Pi[3]; 1426bf688a0SCe Qin Mat ND_PiFull, ND_Pi[3]; 1434cb006feSStefano Zampini PetscBool ams_beta_is_zero; 14423df4f25SStefano Zampini PetscBool ams_beta_is_zero_part; 14523df4f25SStefano Zampini PetscInt ams_proj_freq; 14616d9e3a6SLisandro Dalcin } PC_HYPRE; 14716d9e3a6SLisandro Dalcin 148fd2dd295SFande Kong /* 1498a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1508a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1518a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 152fd2dd295SFande Kong */ 153d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc, PetscInt *nlevels, Mat *operators[]) 154d71ae5a4SJacob Faibussowitsch { 1558a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1568a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1578a2c336bSFande Kong PetscInt num_levels, l; 1588a2c336bSFande Kong Mat *mattmp; 1598a2c336bSFande Kong hypre_ParCSRMatrix **A_array; 1608a2c336bSFande Kong 1618a2c336bSFande Kong PetscFunctionBegin; 1629566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same)); 1635f80ce2aSJacob Faibussowitsch PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG "); 164f4f49eeaSPierre Jolivet num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)jac->hsolver); 1659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels, &mattmp)); 166f4f49eeaSPierre Jolivet A_array = hypre_ParAMGDataAArray((hypre_ParAMGData *)jac->hsolver); 1678a2c336bSFande Kong for (l = 1; l < num_levels; l++) { 168f4f49eeaSPierre Jolivet PetscCall(MatCreateFromParCSR(A_array[l], MATAIJ, PETSC_OWN_POINTER, &mattmp[num_levels - 1 - l])); 1698a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 1708a2c336bSFande Kong A_array[l] = NULL; 1718a2c336bSFande Kong } 1728a2c336bSFande Kong *nlevels = num_levels; 1738a2c336bSFande Kong *operators = mattmp; 1743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1758a2c336bSFande Kong } 1768a2c336bSFande Kong 177fd2dd295SFande Kong /* 1788a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1798a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1808a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 181fd2dd295SFande Kong */ 182d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc, PetscInt *nlevels, Mat *interpolations[]) 183d71ae5a4SJacob Faibussowitsch { 1848a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1858a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1868a2c336bSFande Kong PetscInt num_levels, l; 1878a2c336bSFande Kong Mat *mattmp; 1888a2c336bSFande Kong hypre_ParCSRMatrix **P_array; 1898a2c336bSFande Kong 1908a2c336bSFande Kong PetscFunctionBegin; 1919566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same)); 1925f80ce2aSJacob Faibussowitsch PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG "); 193f4f49eeaSPierre Jolivet num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)jac->hsolver); 1949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels, &mattmp)); 195f4f49eeaSPierre Jolivet P_array = hypre_ParAMGDataPArray((hypre_ParAMGData *)jac->hsolver); 1968a2c336bSFande Kong for (l = 1; l < num_levels; l++) { 197f4f49eeaSPierre Jolivet PetscCall(MatCreateFromParCSR(P_array[num_levels - 1 - l], MATAIJ, PETSC_OWN_POINTER, &mattmp[l - 1])); 1988a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 1998a2c336bSFande Kong P_array[num_levels - 1 - l] = NULL; 2008a2c336bSFande Kong } 2018a2c336bSFande Kong *nlevels = num_levels; 2028a2c336bSFande Kong *interpolations = mattmp; 2033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2048a2c336bSFande Kong } 2058a2c336bSFande Kong 206ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */ 207d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc) 208d71ae5a4SJacob Faibussowitsch { 209ce6a8a0dSJed Brown PC_HYPRE *jac = (PC_HYPRE *)pc->data; 210ce6a8a0dSJed Brown PetscInt i; 211ce6a8a0dSJed Brown 2129d678128SJed Brown PetscFunctionBegin; 21348a46eb9SPierre Jolivet for (i = 0; i < jac->n_hmnull; i++) PetscCall(VecHYPRE_IJVectorDestroy(&jac->hmnull[i])); 2149566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hmnull)); 2159566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->phmnull)); 2169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->hmnull_constant)); 2179d678128SJed Brown jac->n_hmnull = 0; 2183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 219ce6a8a0dSJed Brown } 220ce6a8a0dSJed Brown 221d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_HYPRE(PC pc) 222d71ae5a4SJacob Faibussowitsch { 22316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 22449a781f5SStefano Zampini Mat_HYPRE *hjac; 22516d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 22616d9e3a6SLisandro Dalcin HYPRE_ParVector bv, xv; 22749a781f5SStefano Zampini PetscBool ishypre; 22816d9e3a6SLisandro Dalcin 22916d9e3a6SLisandro Dalcin PetscFunctionBegin; 2300df1829cSStefano Zampini /* default type is boomerAMG */ 23148a46eb9SPierre Jolivet if (!jac->hypre_type) PetscCall(PCHYPRESetType(pc, "boomeramg")); 2325f5c5b43SBarry Smith 2330df1829cSStefano Zampini /* get hypre matrix */ 2340df1829cSStefano Zampini if (pc->flag == DIFFERENT_NONZERO_PATTERN) PetscCall(MatDestroy(&jac->hpmat)); 2359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRE, &ishypre)); 23649a781f5SStefano Zampini if (!ishypre) { 2370df1829cSStefano Zampini /* Temporary fix since we do not support MAT_REUSE_MATRIX with HYPRE device */ 2380df1829cSStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 2390df1829cSStefano Zampini PetscBool iscuda, iship, iskokkos; 2400df1829cSStefano Zampini 2410df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iscuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, "")); 2420df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iship, MATSEQAIJHIPSPARSE, MATMPIAIJHIPSPARSE, "")); 2430df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iskokkos, MATSEQAIJKOKKOS, MATMPIAIJKOKKOS, "")); 2440df1829cSStefano Zampini if (iscuda || iship || iskokkos) PetscCall(MatDestroy(&jac->hpmat)); 2450df1829cSStefano Zampini #endif 2460df1829cSStefano Zampini PetscCall(MatConvert(pc->pmat, MATHYPRE, jac->hpmat ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX, &jac->hpmat)); 24749a781f5SStefano Zampini } else { 2489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc->pmat)); 2499566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 25049a781f5SStefano Zampini jac->hpmat = pc->pmat; 25116d9e3a6SLisandro Dalcin } 2520df1829cSStefano Zampini 2536ea7df73SStefano Zampini /* allow debug */ 2549566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(jac->hpmat, NULL, "-pc_hypre_mat_view")); 255f4f49eeaSPierre Jolivet hjac = (Mat_HYPRE *)jac->hpmat->data; 2565f5c5b43SBarry Smith 25716d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 25816d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 2595272c319SBarry Smith MatNullSpace mnull; 2605272c319SBarry Smith PetscBool has_const; 26149a781f5SStefano Zampini PetscInt bs, nvec, i; 2625272c319SBarry Smith const Vec *vecs; 2635272c319SBarry Smith 2649566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat, &bs)); 265792fecdfSBarry Smith if (bs > 1) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 2669566063dSJacob Faibussowitsch PetscCall(MatGetNearNullSpace(pc->mat, &mnull)); 2675272c319SBarry Smith if (mnull) { 2689566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 2699566063dSJacob Faibussowitsch PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs)); 2709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->hmnull)); 2719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->phmnull)); 2725272c319SBarry Smith for (i = 0; i < nvec; i++) { 2739566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map, &jac->hmnull[i])); 2749566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(vecs[i], jac->hmnull[i])); 275792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[i]->ij, (void **)&jac->phmnull[i]); 2765272c319SBarry Smith } 2775272c319SBarry Smith if (has_const) { 2789566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(pc->pmat, &jac->hmnull_constant, NULL)); 2799566063dSJacob Faibussowitsch PetscCall(VecSet(jac->hmnull_constant, 1)); 2809566063dSJacob Faibussowitsch PetscCall(VecNormalize(jac->hmnull_constant, NULL)); 2819566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map, &jac->hmnull[nvec])); 2829566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant, jac->hmnull[nvec])); 283792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[nvec]->ij, (void **)&jac->phmnull[nvec]); 2845272c319SBarry Smith nvec++; 2855272c319SBarry Smith } 286792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVectors, jac->hsolver, nvec, jac->phmnull); 2875272c319SBarry Smith jac->n_hmnull = nvec; 2885272c319SBarry Smith } 2894cb006feSStefano Zampini } 290863406b8SStefano Zampini 2914cb006feSStefano Zampini /* special case for AMS */ 2924cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 2935ac14e1cSStefano Zampini Mat_HYPRE *hm; 2945ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 2956bf688a0SCe Qin if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 296f1580f4eSBarry 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()"); 2976bf688a0SCe Qin } 29848a46eb9SPierre Jolivet if (jac->dim) PetscCallExternal(HYPRE_AMSSetDimension, jac->hsolver, jac->dim); 2995ac14e1cSStefano Zampini if (jac->constants[0]) { 3005ac14e1cSStefano Zampini HYPRE_ParVector ozz, zoz, zzo = NULL; 301792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[0]->ij, (void **)(&ozz)); 302792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[1]->ij, (void **)(&zoz)); 30348a46eb9SPierre Jolivet if (jac->constants[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[2]->ij, (void **)(&zzo)); 304792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetEdgeConstantVectors, jac->hsolver, ozz, zoz, zzo); 3055ac14e1cSStefano Zampini } 3065ac14e1cSStefano Zampini if (jac->coords[0]) { 3075ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3085ac14e1cSStefano Zampini coords[0] = NULL; 3095ac14e1cSStefano Zampini coords[1] = NULL; 3105ac14e1cSStefano Zampini coords[2] = NULL; 311792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 312792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 313792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 314792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 3155ac14e1cSStefano Zampini } 3165f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 317f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->G->data; 318792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 319792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDiscreteGradient, jac->hsolver, parcsr); 3205ac14e1cSStefano Zampini if (jac->alpha_Poisson) { 321f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->alpha_Poisson->data; 322792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 323792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaPoissonMatrix, jac->hsolver, parcsr); 3245ac14e1cSStefano Zampini } 3255ac14e1cSStefano Zampini if (jac->ams_beta_is_zero) { 326792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, NULL); 3275ac14e1cSStefano Zampini } else if (jac->beta_Poisson) { 328f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->beta_Poisson->data; 329792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 330792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, parcsr); 331be14dc20SKerry Key } else if (jac->ams_beta_is_zero_part) { 332be14dc20SKerry Key if (jac->interior) { 333be14dc20SKerry Key HYPRE_ParVector interior = NULL; 334be14dc20SKerry Key PetscCallExternal(HYPRE_IJVectorGetObject, jac->interior->ij, (void **)(&interior)); 335be14dc20SKerry Key PetscCallExternal(HYPRE_AMSSetInteriorNodes, jac->hsolver, interior); 336be14dc20SKerry Key } else { 337be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 338be14dc20SKerry Key } 3395ac14e1cSStefano Zampini } 3406bf688a0SCe Qin if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) { 3416bf688a0SCe Qin PetscInt i; 3426bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3436bf688a0SCe Qin if (jac->ND_PiFull) { 344f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_PiFull->data; 345792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 3466bf688a0SCe Qin } else { 3476bf688a0SCe Qin nd_parcsrfull = NULL; 3486bf688a0SCe Qin } 3496bf688a0SCe Qin for (i = 0; i < 3; ++i) { 3506bf688a0SCe Qin if (jac->ND_Pi[i]) { 351f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_Pi[i]->data; 352792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 3536bf688a0SCe Qin } else { 3546bf688a0SCe Qin nd_parcsr[i] = NULL; 3556bf688a0SCe Qin } 3566bf688a0SCe Qin } 357792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetInterpolations, jac->hsolver, nd_parcsrfull, nd_parcsr[0], nd_parcsr[1], nd_parcsr[2]); 3586bf688a0SCe Qin } 3594cb006feSStefano Zampini } 360863406b8SStefano Zampini /* special case for ADS */ 361863406b8SStefano Zampini if (jac->setup == HYPRE_ADSSetup) { 3625ac14e1cSStefano Zampini Mat_HYPRE *hm; 3635ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 3646bf688a0SCe 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])))) { 3656bf688a0SCe Qin SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations"); 3669371c9d4SSatish 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"); 3675f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3685f80ce2aSJacob Faibussowitsch PetscCheck(jac->C, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient"); 3695ac14e1cSStefano Zampini if (jac->coords[0]) { 3705ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3715ac14e1cSStefano Zampini coords[0] = NULL; 3725ac14e1cSStefano Zampini coords[1] = NULL; 3735ac14e1cSStefano Zampini coords[2] = NULL; 374792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 375792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 376792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 377792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 3785ac14e1cSStefano Zampini } 379f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->G->data; 380792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 381792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteGradient, jac->hsolver, parcsr); 382f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->C->data; 383792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 384792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteCurl, jac->hsolver, parcsr); 3856bf688a0SCe Qin if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 3866bf688a0SCe Qin PetscInt i; 3876bf688a0SCe Qin HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3]; 3886bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3896bf688a0SCe Qin if (jac->RT_PiFull) { 390f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->RT_PiFull->data; 391792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsrfull)); 3926bf688a0SCe Qin } else { 3936bf688a0SCe Qin rt_parcsrfull = NULL; 3946bf688a0SCe Qin } 3956bf688a0SCe Qin for (i = 0; i < 3; ++i) { 3966bf688a0SCe Qin if (jac->RT_Pi[i]) { 397f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->RT_Pi[i]->data; 398792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsr[i])); 3996bf688a0SCe Qin } else { 4006bf688a0SCe Qin rt_parcsr[i] = NULL; 4016bf688a0SCe Qin } 4026bf688a0SCe Qin } 4036bf688a0SCe Qin if (jac->ND_PiFull) { 404f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_PiFull->data; 405792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 4066bf688a0SCe Qin } else { 4076bf688a0SCe Qin nd_parcsrfull = NULL; 4086bf688a0SCe Qin } 4096bf688a0SCe Qin for (i = 0; i < 3; ++i) { 4106bf688a0SCe Qin if (jac->ND_Pi[i]) { 411f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_Pi[i]->data; 412792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 4136bf688a0SCe Qin } else { 4146bf688a0SCe Qin nd_parcsr[i] = NULL; 4156bf688a0SCe Qin } 4166bf688a0SCe Qin } 417792fecdfSBarry 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]); 4186bf688a0SCe Qin } 419863406b8SStefano Zampini } 420792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 421792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&bv); 422792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&xv); 42397c1e3cbSStefano Zampini PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 424792fecdfSBarry Smith PetscCallExternal(jac->setup, jac->hsolver, hmat, bv, xv); 42597c1e3cbSStefano Zampini PetscCall(PetscFPTrapPop()); 4263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42716d9e3a6SLisandro Dalcin } 42816d9e3a6SLisandro Dalcin 429d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_HYPRE(PC pc, Vec b, Vec x) 430d71ae5a4SJacob Faibussowitsch { 43116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 432f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 43316d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 43416d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 43516d9e3a6SLisandro Dalcin 43616d9e3a6SLisandro Dalcin PetscFunctionBegin; 4379566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 4389566063dSJacob Faibussowitsch if (!jac->applyrichardson) PetscCall(VecSet(x, 0.0)); 4399566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b, b)); 4409566063dSJacob Faibussowitsch if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x, x)); 4419566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x, x)); 442792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 443792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 444792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 4459371c9d4SSatish Balay PetscStackCallExternalVoid( 4469371c9d4SSatish Balay "Hypre solve", do { 4475f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = (*jac->solve)(jac->hsolver, hmat, jbv, jxv); 4485f80ce2aSJacob Faibussowitsch if (hierr) { 4495f80ce2aSJacob Faibussowitsch PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 45085245615SPierre Jolivet HYPRE_ClearAllErrors(); 4515f80ce2aSJacob Faibussowitsch } 4525f80ce2aSJacob Faibussowitsch } while (0)); 45316d9e3a6SLisandro Dalcin 45448a46eb9SPierre Jolivet if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) PetscCallExternal(HYPRE_AMSProjectOutGradients, jac->hsolver, jxv); 4559566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 4569566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 4573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45816d9e3a6SLisandro Dalcin } 45916d9e3a6SLisandro Dalcin 46085245615SPierre Jolivet static PetscErrorCode PCMatApply_HYPRE_BoomerAMG(PC pc, Mat B, Mat X) 46185245615SPierre Jolivet { 46285245615SPierre Jolivet PC_HYPRE *jac = (PC_HYPRE *)pc->data; 463f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 46485245615SPierre Jolivet hypre_ParCSRMatrix *par_matrix; 46585245615SPierre Jolivet HYPRE_ParVector hb, hx; 46685245615SPierre Jolivet const PetscScalar *b; 46785245615SPierre Jolivet PetscScalar *x; 46885245615SPierre Jolivet PetscInt m, N, lda; 46985245615SPierre Jolivet hypre_Vector *x_local; 47085245615SPierre Jolivet PetscMemType type; 47185245615SPierre Jolivet 47285245615SPierre Jolivet PetscFunctionBegin; 47385245615SPierre Jolivet PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 47485245615SPierre Jolivet PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&par_matrix); 47585245615SPierre Jolivet PetscCall(MatGetLocalSize(B, &m, NULL)); 47685245615SPierre Jolivet PetscCall(MatGetSize(B, NULL, &N)); 47785245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hb); 47885245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hx); 47985245615SPierre Jolivet PetscCall(MatZeroEntries(X)); 48085245615SPierre Jolivet PetscCall(MatDenseGetArrayReadAndMemType(B, &b, &type)); 48185245615SPierre Jolivet PetscCall(MatDenseGetLDA(B, &lda)); 48285245615SPierre 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); 48385245615SPierre Jolivet PetscCall(MatDenseGetLDA(X, &lda)); 48485245615SPierre 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); 48585245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hb); 48685245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 48785245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)b; 48885245615SPierre Jolivet PetscCall(MatDenseGetArrayWriteAndMemType(X, &x, NULL)); 48985245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hx); 49085245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 49185245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)x; 49285245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hb, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 49385245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hx, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 49485245615SPierre Jolivet PetscStackCallExternalVoid( 49585245615SPierre Jolivet "Hypre solve", do { 49685245615SPierre Jolivet HYPRE_Int hierr = (*jac->solve)(jac->hsolver, par_matrix, hb, hx); 49785245615SPierre Jolivet if (hierr) { 49885245615SPierre Jolivet PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 49985245615SPierre Jolivet HYPRE_ClearAllErrors(); 50085245615SPierre Jolivet } 50185245615SPierre Jolivet } while (0)); 50285245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hb); 50385245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hx); 50485245615SPierre Jolivet PetscCall(MatDenseRestoreArrayReadAndMemType(B, &b)); 50585245615SPierre Jolivet PetscCall(MatDenseRestoreArrayWriteAndMemType(X, &x)); 50685245615SPierre Jolivet PetscFunctionReturn(PETSC_SUCCESS); 50785245615SPierre Jolivet } 50885245615SPierre Jolivet 509d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_HYPRE(PC pc) 510d71ae5a4SJacob Faibussowitsch { 5118695de01SBarry Smith PC_HYPRE *jac = (PC_HYPRE *)pc->data; 5128695de01SBarry Smith 5138695de01SBarry Smith PetscFunctionBegin; 5149566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 5159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 5169566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 5179566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 5189566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 5199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 5209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[0])); 5219566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[1])); 5229566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[2])); 5239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 5249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[0])); 5259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[1])); 5269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[2])); 5279566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 5289566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 5299566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 5309566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 5319566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 5329566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 533be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 5349566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 5355ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 536be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 5375ac14e1cSStefano Zampini jac->dim = 0; 5383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5398695de01SBarry Smith } 5408695de01SBarry Smith 541d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_HYPRE(PC pc) 542d71ae5a4SJacob Faibussowitsch { 54316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 54416d9e3a6SLisandro Dalcin 54516d9e3a6SLisandro Dalcin PetscFunctionBegin; 5469566063dSJacob Faibussowitsch PetscCall(PCReset_HYPRE(pc)); 547792fecdfSBarry Smith if (jac->destroy) PetscCallExternal(jac->destroy, jac->hsolver); 5489566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 549db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 5509566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->spgemm_type)); 551db6f9c32SMark Adams #endif 5529566063dSJacob Faibussowitsch if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 5539566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 55416d9e3a6SLisandro Dalcin 5559566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc, 0)); 5569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", NULL)); 5579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", NULL)); 5589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", NULL)); 5599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", NULL)); 5609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", NULL)); 5619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetConstantEdgeVectors_C", NULL)); 5629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", NULL)); 5632e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", NULL)); 564be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", NULL)); 5659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", NULL)); 5669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", NULL)); 5679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", NULL)); 5689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", NULL)); 5692e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", NULL)); 5703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57116d9e3a6SLisandro Dalcin } 57216d9e3a6SLisandro Dalcin 573d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc, PetscOptionItems *PetscOptionsObject) 574d71ae5a4SJacob Faibussowitsch { 57516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 576ace3abfcSBarry Smith PetscBool flag; 57716d9e3a6SLisandro Dalcin 57816d9e3a6SLisandro Dalcin PetscFunctionBegin; 579d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Pilut Options"); 5809566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter", "Number of iterations", "None", jac->maxiter, &jac->maxiter, &flag)); 581792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetMaxIter, jac->hsolver, jac->maxiter); 5829566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol", "Drop tolerance", "None", jac->tol, &jac->tol, &flag)); 583792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetDropTolerance, jac->hsolver, jac->tol); 5849566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize", "FactorRowSize", "None", jac->factorrowsize, &jac->factorrowsize, &flag)); 585792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetFactorRowSize, jac->hsolver, jac->factorrowsize); 586d0609cedSBarry Smith PetscOptionsHeadEnd(); 5873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58816d9e3a6SLisandro Dalcin } 58916d9e3a6SLisandro Dalcin 590d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Pilut(PC pc, PetscViewer viewer) 591d71ae5a4SJacob Faibussowitsch { 59216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 593ace3abfcSBarry Smith PetscBool iascii; 59416d9e3a6SLisandro Dalcin 59516d9e3a6SLisandro Dalcin PetscFunctionBegin; 5969566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 59716d9e3a6SLisandro Dalcin if (iascii) { 5989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Pilut preconditioning\n")); 59916d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 60063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum number of iterations %" PetscInt_FMT "\n", jac->maxiter)); 60116d9e3a6SLisandro Dalcin } else { 6029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default maximum number of iterations \n")); 60316d9e3a6SLisandro Dalcin } 60416d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 6059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->tol)); 60616d9e3a6SLisandro Dalcin } else { 6079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default drop tolerance \n")); 60816d9e3a6SLisandro Dalcin } 60916d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 61063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factor row size %" PetscInt_FMT "\n", jac->factorrowsize)); 61116d9e3a6SLisandro Dalcin } else { 6129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factor row size \n")); 61316d9e3a6SLisandro Dalcin } 61416d9e3a6SLisandro Dalcin } 6153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 61616d9e3a6SLisandro Dalcin } 61716d9e3a6SLisandro Dalcin 6183c61a47dSLukas static const char *HYPREILUType[] = { 6193c61a47dSLukas "Block-Jacobi-ILUk", "Block-Jacobi-ILUT", "", "", "", "", "", "", "", "", /* 0-9 */ 6203c61a47dSLukas "GMRES-ILUk", "GMRES-ILUT", "", "", "", "", "", "", "", "", /* 10-19 */ 6213c61a47dSLukas "NSH-ILUk", "NSH-ILUT", "", "", "", "", "", "", "", "", /* 20-29 */ 6223c61a47dSLukas "RAS-ILUk", "RAS-ILUT", "", "", "", "", "", "", "", "", /* 30-39 */ 6233c61a47dSLukas "ddPQ-GMRES-ILUk", "ddPQ-GMRES-ILUT", "", "", "", "", "", "", "", "", /* 40-49 */ 6243c61a47dSLukas "GMRES-ILU0" /* 50 */ 6253c61a47dSLukas }; 6263c61a47dSLukas 6273c61a47dSLukas static const char *HYPREILUIterSetup[] = {"default", "async-in-place", "async-explicit", "sync-explicit", "semisync-explicit"}; 6283c61a47dSLukas 6293c61a47dSLukas static PetscErrorCode PCSetFromOptions_HYPRE_ILU(PC pc, PetscOptionItems *PetscOptionsObject) 6303c61a47dSLukas { 6313c61a47dSLukas PC_HYPRE *jac = (PC_HYPRE *)pc->data; 6323c61a47dSLukas PetscBool flg; 6333c61a47dSLukas PetscInt indx; 6343c61a47dSLukas PetscReal tmpdbl; 6353c61a47dSLukas PetscBool tmp_truth; 6363c61a47dSLukas 6373c61a47dSLukas PetscFunctionBegin; 6383c61a47dSLukas PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ILU Options"); 6393c61a47dSLukas 6403c61a47dSLukas /* ILU: ILU Type */ 6413c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_ilu_type", "Choose ILU Type", "None", HYPREILUType, PETSC_STATIC_ARRAY_LENGTH(HYPREILUType), HYPREILUType[0], &indx, &flg)); 6423c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetType, jac->hsolver, indx); } 6433c61a47dSLukas 6443c61a47dSLukas /* ILU: ILU iterative setup type*/ 6453c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_ilu_iterative_setup_type", "Set ILU iterative setup type", "None", HYPREILUIterSetup, PETSC_STATIC_ARRAY_LENGTH(HYPREILUIterSetup), HYPREILUIterSetup[0], &indx, &flg)); 6463c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetIterativeSetupType, jac->hsolver, indx); } 6473c61a47dSLukas 6483c61a47dSLukas /* ILU: ILU iterative setup option*/ 6493c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_iterative_setup_option", "Set ILU iterative setup option", "None", 0, &indx, &flg)); 6503c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetIterativeSetupOption, jac->hsolver, indx); } 6513c61a47dSLukas 6523c61a47dSLukas /* ILU: ILU iterative setup maxiter */ 6533c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_iterative_setup_maxiter", "Set ILU iterative setup maximum iteration count", "None", 0, &indx, &flg)); 6543c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetIterativeSetupMaxIter, jac->hsolver, indx); } 6553c61a47dSLukas 6563c61a47dSLukas /* ILU: ILU iterative setup tolerance */ 6573c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_iterative_setup_tolerance", "Set ILU iterative setup tolerance", "None", 0, &tmpdbl, &flg)); 6583c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetIterativeSetupTolerance, jac->hsolver, tmpdbl); } 6593c61a47dSLukas 6603c61a47dSLukas /* ILU: ILU Print Level */ 6613c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_print_level", "Set ILU print level", "None", 0, &indx, &flg)); 6623c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetPrintLevel, jac->hsolver, indx); } 6633c61a47dSLukas 6643c61a47dSLukas /* ILU: Logging */ 6653c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_logging", "Set ILU logging level", "None", 0, &indx, &flg)); 6663c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetLogging, jac->hsolver, indx); } 6673c61a47dSLukas 6683c61a47dSLukas /* ILU: ILU Level */ 6693c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_level", "Set ILU level", "None", 0, &indx, &flg)); 6703c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetLevelOfFill, jac->hsolver, indx); } 6713c61a47dSLukas 6723c61a47dSLukas /* ILU: ILU Max NNZ per row */ 6733c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_max_nnz_per_row", "Set maximum NNZ per row", "None", 0, &indx, &flg)); 6743c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetMaxNnzPerRow, jac->hsolver, indx); } 6753c61a47dSLukas 6763c61a47dSLukas /* ILU: tolerance */ 6773c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_tol", "Tolerance for ILU", "None", 0, &tmpdbl, &flg)); 6783c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetTol, jac->hsolver, tmpdbl); } 6793c61a47dSLukas 6803c61a47dSLukas /* ILU: maximum iteration count */ 6813c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_maxiter", "Set ILU max iterations", "None", 0, &indx, &flg)); 6823c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetMaxIter, jac->hsolver, indx); } 6833c61a47dSLukas 6843c61a47dSLukas /* ILU: drop threshold */ 6853c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_drop_threshold", "Drop threshold for ILU", "None", 0, &tmpdbl, &flg)); 6863c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetDropThreshold, jac->hsolver, tmpdbl); } 6873c61a47dSLukas 6883c61a47dSLukas /* ILU: Triangular Solve */ 6893c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_ilu_tri_solve", "Enable triangular solve", "None", PETSC_FALSE, &tmp_truth, &flg)); 6903c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetTriSolve, jac->hsolver, tmp_truth); } 6913c61a47dSLukas 6923c61a47dSLukas /* ILU: Lower Jacobi iteration */ 6933c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_lower_jacobi_iters", "Set lower Jacobi iteration count", "None", 0, &indx, &flg)); 6943c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetLowerJacobiIters, jac->hsolver, indx); } 6953c61a47dSLukas 6963c61a47dSLukas /* ILU: Upper Jacobi iteration */ 6973c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_upper_jacobi_iters", "Set upper Jacobi iteration count", "None", 0, &indx, &flg)); 6983c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetUpperJacobiIters, jac->hsolver, indx); } 6993c61a47dSLukas 7003c61a47dSLukas /* ILU: local reordering */ 7013c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_ilu_local_reordering", "Enable local reordering", "None", PETSC_FALSE, &tmp_truth, &flg)); 7023c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_ILUSetLocalReordering, jac->hsolver, tmp_truth); } 7033c61a47dSLukas 7043c61a47dSLukas PetscOptionsHeadEnd(); 7053c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 7063c61a47dSLukas } 7073c61a47dSLukas 7083c61a47dSLukas static PetscErrorCode PCView_HYPRE_ILU(PC pc, PetscViewer viewer) 7093c61a47dSLukas { 7103c61a47dSLukas PC_HYPRE *jac = (PC_HYPRE *)pc->data; 7113c61a47dSLukas hypre_ParILUData *ilu_data = (hypre_ParILUData *)jac->hsolver; 7123c61a47dSLukas PetscBool iascii; 7133c61a47dSLukas PetscInt indx; 7143c61a47dSLukas PetscReal tmpdbl; 7153c61a47dSLukas PetscReal *tmpdbl3; 7163c61a47dSLukas 7173c61a47dSLukas PetscFunctionBegin; 7183c61a47dSLukas PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 7193c61a47dSLukas if (iascii) { 7203c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ILU preconditioning\n")); 7213c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIluType", indx = hypre_ParILUDataIluType(ilu_data)); 7223c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU type %s (%" PetscInt_FMT ")\n", HYPREILUType[indx], indx)); 7233c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLfil", indx = hypre_ParILUDataLfil(ilu_data)); 7243c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU level %" PetscInt_FMT "\n", indx)); 7253c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataMaxIter", indx = hypre_ParILUDataMaxIter(ilu_data)); 7263c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max iterations %" PetscInt_FMT "\n", indx)); 7273c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataMaxRowNnz", indx = hypre_ParILUDataMaxRowNnz(ilu_data)); 7283c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max NNZ per row %" PetscInt_FMT "\n", indx)); 7293c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataTriSolve", indx = hypre_ParILUDataTriSolve(ilu_data)); 7303c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU triangular solve %" PetscInt_FMT "\n", indx)); 7313c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataTol", tmpdbl = hypre_ParILUDataTol(ilu_data)); 7323c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU tolerance %e\n", tmpdbl)); 7333c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataDroptol", tmpdbl3 = hypre_ParILUDataDroptol(ilu_data)); 7343c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU drop tolerance %e / %e / %e\n", tmpdbl3[0], tmpdbl3[1], tmpdbl3[2])); 7353c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataReorderingType", indx = hypre_ParILUDataReorderingType(ilu_data)); 7363c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU local reordering %" PetscInt_FMT "\n", indx)); 7373c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLowerJacobiIters", indx = hypre_ParILUDataLowerJacobiIters(ilu_data)); 7383c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU lower Jacobi iterations %" PetscInt_FMT "\n", indx)); 7393c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataUpperJacobiIters", indx = hypre_ParILUDataUpperJacobiIters(ilu_data)); 7403c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU upper Jacobi iterations %" PetscInt_FMT "\n", indx)); 7413c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataPrintLevel", indx = hypre_ParILUDataPrintLevel(ilu_data)); 7423c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU print level %" PetscInt_FMT "\n", indx)); 7433c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLogging", indx = hypre_ParILUDataLogging(ilu_data)); 7443c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU logging level %" PetscInt_FMT "\n", indx)); 7453c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupType", indx = hypre_ParILUDataIterativeSetupType(ilu_data)); 7463c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup type %s (%" PetscInt_FMT ")\n", HYPREILUIterSetup[indx], indx)); 7473c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupOption", indx = hypre_ParILUDataIterativeSetupOption(ilu_data)); 7483c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup option %" PetscInt_FMT "\n", indx)); 7493c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupMaxIter", indx = hypre_ParILUDataIterativeSetupMaxIter(ilu_data)); 7503c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup max iterations %" PetscInt_FMT "\n", indx)); 7513c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupTolerance", tmpdbl = hypre_ParILUDataIterativeSetupTolerance(ilu_data)); 7523c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup tolerance %e\n", tmpdbl)); 7533c61a47dSLukas } 7543c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 7553c61a47dSLukas } 7563c61a47dSLukas 757d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc, PetscOptionItems *PetscOptionsObject) 758d71ae5a4SJacob Faibussowitsch { 759db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 7608bf83915SBarry Smith PetscBool flag, eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE; 761db966c6cSHong Zhang 762db966c6cSHong Zhang PetscFunctionBegin; 763d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Euclid Options"); 7649566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_euclid_level", "Factorization levels", "None", jac->eu_level, &jac->eu_level, &flag)); 765792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_EuclidSetLevel, jac->hsolver, jac->eu_level); 7668bf83915SBarry Smith 7679566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_euclid_droptolerance", "Drop tolerance for ILU(k) in Euclid", "None", jac->eu_droptolerance, &jac->eu_droptolerance, &flag)); 7688bf83915SBarry Smith if (flag) { 7698bf83915SBarry Smith PetscMPIInt size; 7708bf83915SBarry Smith 7719566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc), &size)); 7727827d75bSBarry Smith PetscCheck(size == 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "hypre's Euclid does not support a parallel drop tolerance"); 773792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetILUT, jac->hsolver, jac->eu_droptolerance); 7748bf83915SBarry Smith } 7758bf83915SBarry Smith 7769566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj, &eu_bj, &flag)); 7778bf83915SBarry Smith if (flag) { 7788bf83915SBarry Smith jac->eu_bj = eu_bj ? 1 : 0; 779792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetBJ, jac->hsolver, jac->eu_bj); 7808bf83915SBarry Smith } 781d0609cedSBarry Smith PetscOptionsHeadEnd(); 7823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 783db966c6cSHong Zhang } 784db966c6cSHong Zhang 785d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Euclid(PC pc, PetscViewer viewer) 786d71ae5a4SJacob Faibussowitsch { 787db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 788db966c6cSHong Zhang PetscBool iascii; 789db966c6cSHong Zhang 790db966c6cSHong Zhang PetscFunctionBegin; 7919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 792db966c6cSHong Zhang if (iascii) { 7939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Euclid preconditioning\n")); 794db966c6cSHong Zhang if (jac->eu_level != PETSC_DEFAULT) { 79563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factorization levels %" PetscInt_FMT "\n", jac->eu_level)); 796db966c6cSHong Zhang } else { 7979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factorization levels \n")); 798db966c6cSHong Zhang } 7999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->eu_droptolerance)); 80063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 801db966c6cSHong Zhang } 8023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 803db966c6cSHong Zhang } 804db966c6cSHong Zhang 805d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc, Vec b, Vec x) 806d71ae5a4SJacob Faibussowitsch { 80716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 808f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 80916d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 81016d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 81116d9e3a6SLisandro Dalcin 81216d9e3a6SLisandro Dalcin PetscFunctionBegin; 8139566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 8149566063dSJacob Faibussowitsch PetscCall(VecSet(x, 0.0)); 8159566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->x, b)); 8169566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->b, x)); 81716d9e3a6SLisandro Dalcin 818792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 819792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 820792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 82116d9e3a6SLisandro Dalcin 8229371c9d4SSatish Balay PetscStackCallExternalVoid( 8239371c9d4SSatish Balay "Hypre Transpose solve", do { 8245f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver, hmat, jbv, jxv); 8255f80ce2aSJacob Faibussowitsch if (hierr) { 82616d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 8275f80ce2aSJacob Faibussowitsch PetscCheck(hierr == 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 82885245615SPierre Jolivet HYPRE_ClearAllErrors(); 8295f80ce2aSJacob Faibussowitsch } 8305f80ce2aSJacob Faibussowitsch } while (0)); 83116d9e3a6SLisandro Dalcin 8329566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 8339566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 8343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83516d9e3a6SLisandro Dalcin } 83616d9e3a6SLisandro Dalcin 837d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char name[]) 838d71ae5a4SJacob Faibussowitsch { 839db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 840db6f9c32SMark Adams PetscBool flag; 841db6f9c32SMark Adams 842db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 843db6f9c32SMark Adams PetscFunctionBegin; 844db6f9c32SMark Adams if (jac->spgemm_type) { 8459566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->spgemm_type, name, &flag)); 84628b400f6SJacob Faibussowitsch PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "Cannot reset the HYPRE SpGEMM (really we can)"); 8473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 848db6f9c32SMark Adams } else { 8499566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->spgemm_type)); 850db6f9c32SMark Adams } 8519566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("cusparse", jac->spgemm_type, &flag)); 852db6f9c32SMark Adams if (flag) { 853792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 1); 8543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 855db6f9c32SMark Adams } 8569566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("hypre", jac->spgemm_type, &flag)); 857db6f9c32SMark Adams if (flag) { 858792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 0); 8593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 860db6f9c32SMark Adams } 861db6f9c32SMark Adams jac->spgemm_type = NULL; 8622d6c3ceeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE SpGEMM type %s; Choices are cusparse, hypre", name); 863db6f9c32SMark Adams #endif 864db6f9c32SMark Adams } 865db6f9c32SMark Adams 866d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[]) 867d71ae5a4SJacob Faibussowitsch { 868db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 869db6f9c32SMark Adams 870db6f9c32SMark Adams PetscFunctionBegin; 871db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 872db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 873db6f9c32SMark Adams *spgemm = jac->spgemm_type; 874db6f9c32SMark Adams #endif 8753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 876db6f9c32SMark Adams } 877db6f9c32SMark Adams 87816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"", "V", "W"}; 8790f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP", "Ruge-Stueben", "", "modifiedRuge-Stueben", "", "", "Falgout", "", "PMIS", "", "HMIS"}; 88016d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local", "global"}; 88165de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 8823c61a47dSLukas static const char *HYPREBoomerAMGSmoothType[] = {"ILU", "Schwarz-smoothers", "Pilut", "ParaSails", "Euclid"}; 8839371c9d4SSatish 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"}; 8849371c9d4SSatish 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"}; 885d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc, PetscOptionItems *PetscOptionsObject) 886d71ae5a4SJacob Faibussowitsch { 88716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 88822e51d31SStefano Zampini PetscInt bs, n, indx, level; 889ace3abfcSBarry Smith PetscBool flg, tmp_truth; 89073dcfd97SStefano Zampini PetscReal tmpdbl, twodbl[2]; 891589dcaf0SStefano Zampini const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 892db6f9c32SMark Adams const char *PCHYPRESpgemmTypes[] = {"cusparse", "hypre"}; 89316d9e3a6SLisandro Dalcin 89416d9e3a6SLisandro Dalcin PetscFunctionBegin; 895d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE BoomerAMG Options"); 8969566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type", "Cycle type", "None", HYPREBoomerAMGCycleType + 1, 2, HYPREBoomerAMGCycleType[jac->cycletype], &indx, &flg)); 89716d9e3a6SLisandro Dalcin if (flg) { 8984336a9eeSBarry Smith jac->cycletype = indx + 1; 899792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 90016d9e3a6SLisandro Dalcin } 90152ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_levels", "Number of levels (of grids) allowed", "None", jac->maxlevels, &jac->maxlevels, &flg, 2)); 90252ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 90352ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_iter", "Maximum iterations used PER hypre call", "None", jac->maxiter, &jac->maxiter, &flg, 1)); 90452ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 90552ce0ab5SPierre 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)); 90652ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 90722e51d31SStefano Zampini bs = 1; 90848a46eb9SPierre Jolivet if (pc->pmat) PetscCall(MatGetBlockSize(pc->pmat, &bs)); 9099566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions", "Number of functions", "HYPRE_BoomerAMGSetNumFunctions", bs, &bs, &flg)); 91048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 91116d9e3a6SLisandro Dalcin 91252ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_truncfactor", "Truncation factor for interpolation (0=no truncation)", "None", jac->truncfactor, &jac->truncfactor, &flg, 0.0)); 91352ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 91416d9e3a6SLisandro Dalcin 91552ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_P_max", "Max elements per row for interpolation operator (0=unlimited)", "None", jac->pmax, &jac->pmax, &flg, 0)); 91652ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 9170f1074feSSatish Balay 9189566063dSJacob 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)); 919792fecdfSBarry Smith if (flg) PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 9200f1074feSSatish Balay 92152ce0ab5SPierre 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)); 92252ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 9230f1074feSSatish Balay 92452ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_strong_threshold", "Threshold for being strongly connected", "None", jac->strongthreshold, &jac->strongthreshold, &flg, 0.0)); 92552ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 92652ce0ab5SPierre Jolivet PetscCall(PetscOptionsRangeReal("-pc_hypre_boomeramg_max_row_sum", "Maximum row sum", "None", jac->maxrowsum, &jac->maxrowsum, &flg, 0.0, 1.0)); 92752ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 92816d9e3a6SLisandro Dalcin 92916d9e3a6SLisandro Dalcin /* Grid sweeps */ 9309566063dSJacob 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)); 93116d9e3a6SLisandro Dalcin if (flg) { 932792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps, jac->hsolver, indx); 93316d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 93416d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 9350f1074feSSatish Balay jac->gridsweeps[1] = indx; 9360f1074feSSatish Balay /*defaults coarse to 1 */ 9370f1074feSSatish Balay jac->gridsweeps[2] = 1; 93816d9e3a6SLisandro Dalcin } 9399566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen", "Use a nodal based coarsening 1-6", "HYPRE_BoomerAMGSetNodal", jac->nodal_coarsening, &jac->nodal_coarsening, &flg)); 94048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodal, jac->hsolver, jac->nodal_coarsening); 9419566063dSJacob 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)); 94248a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodalDiag, jac->hsolver, jac->nodal_coarsening_diag); 9439566063dSJacob 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)); 94448a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecVariant, jac->hsolver, jac->vec_interp_variant); 9459566063dSJacob 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)); 94648a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecQMax, jac->hsolver, jac->vec_interp_qmax); 9479566063dSJacob 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)); 94848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetSmoothInterpVectors, jac->hsolver, jac->vec_interp_smooth); 9499566063dSJacob 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)); 95048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpRefine, jac->hsolver, jac->interp_refine); 9519566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down", "Number of sweeps for the down cycles", "None", jac->gridsweeps[0], &indx, &flg)); 95216d9e3a6SLisandro Dalcin if (flg) { 953792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 1); 9540f1074feSSatish Balay jac->gridsweeps[0] = indx; 95516d9e3a6SLisandro Dalcin } 9569566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up", "Number of sweeps for the up cycles", "None", jac->gridsweeps[1], &indx, &flg)); 95716d9e3a6SLisandro Dalcin if (flg) { 958792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 2); 9590f1074feSSatish Balay jac->gridsweeps[1] = indx; 96016d9e3a6SLisandro Dalcin } 9619566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse", "Number of sweeps for the coarse level", "None", jac->gridsweeps[2], &indx, &flg)); 96216d9e3a6SLisandro Dalcin if (flg) { 963792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 3); 9640f1074feSSatish Balay jac->gridsweeps[2] = indx; 96516d9e3a6SLisandro Dalcin } 96616d9e3a6SLisandro Dalcin 9676a251517SEike Mueller /* Smooth type */ 968dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type", "Enable more complex smoothers", "None", HYPREBoomerAMGSmoothType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType), HYPREBoomerAMGSmoothType[0], &indx, &flg)); 9696a251517SEike Mueller if (flg) { 9706a251517SEike Mueller jac->smoothtype = indx; 9713c61a47dSLukas PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, indx + 5); 9728131ecf7SEike Mueller jac->smoothnumlevels = 25; 973792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, 25); 9748131ecf7SEike Mueller } 9758131ecf7SEike Mueller 9768131ecf7SEike Mueller /* Number of smoothing levels */ 9779566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels", "Number of levels on which more complex smoothers are used", "None", 25, &indx, &flg)); 9788131ecf7SEike Mueller if (flg && (jac->smoothtype != -1)) { 9798131ecf7SEike Mueller jac->smoothnumlevels = indx; 980792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, indx); 9816a251517SEike Mueller } 9826a251517SEike Mueller 9833c61a47dSLukas /* Smooth num sweeps */ 9843c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_sweeps", "Set number of smoother sweeps", "None", 1, &indx, &flg)); 9853c61a47dSLukas if (flg && indx > 0) { 9863c61a47dSLukas jac->smoothsweeps = indx; 9873c61a47dSLukas PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumSweeps, jac->hsolver, indx); 9883c61a47dSLukas } 9893c61a47dSLukas 9903c61a47dSLukas /* ILU: ILU Type */ 9913c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_ilu_type", "Choose ILU Type", "None", HYPREILUType, PETSC_STATIC_ARRAY_LENGTH(HYPREILUType), HYPREILUType[0], &indx, &flg)); 9923c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUType, jac->hsolver, indx); } 9933c61a47dSLukas 9943c61a47dSLukas /* ILU: ILU iterative setup type*/ 9953c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_ilu_iterative_setup_type", "Set ILU iterative setup type", "None", HYPREILUIterSetup, PETSC_STATIC_ARRAY_LENGTH(HYPREILUIterSetup), HYPREILUIterSetup[0], &indx, &flg)); 9963c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupType, jac->hsolver, indx); } 9973c61a47dSLukas 9983c61a47dSLukas /* ILU: ILU iterative setup option*/ 9993c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_iterative_setup_option", "Set ILU iterative setup option", "None", 0, &indx, &flg)); 10003c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupOption, jac->hsolver, indx); } 10013c61a47dSLukas 10023c61a47dSLukas /* ILU: ILU iterative setup maxiter */ 10033c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_iterative_setup_maxiter", "Set ILU iterative setup maximum iteration count", "None", 0, &indx, &flg)); 10043c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupMaxIter, jac->hsolver, indx); } 10053c61a47dSLukas 10063c61a47dSLukas /* ILU: ILU iterative setup tolerance */ 10073c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_ilu_iterative_setup_tolerance", "Set ILU iterative setup tolerance", "None", 0, &tmpdbl, &flg)); 10083c61a47dSLukas if (flg) { PetscCallExternal(hypre_BoomerAMGSetILUIterSetupTolerance, jac->hsolver, tmpdbl); } 10093c61a47dSLukas 10103c61a47dSLukas /* ILU: ILU Print Level */ 10113c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_print_level", "Set ILU print level", "None", 0, &indx, &flg)); 10123c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel, jac->hsolver, indx); } 10133c61a47dSLukas 10143c61a47dSLukas /* ILU: Logging */ 10153c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_logging", "Set ILU logging level", "None", 0, &indx, &flg)); 10163c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetLogging, jac->hsolver, indx); } 10173c61a47dSLukas 10183c61a47dSLukas /* ILU: ILU Level */ 10193c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_level", "Set ILU level", "None", 0, &indx, &flg)); 10203c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILULevel, jac->hsolver, indx); } 10213c61a47dSLukas 10223c61a47dSLukas /* ILU: ILU Max NNZ per row */ 10233c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_max_nnz_per_row", "Set maximum NNZ per row", "None", 0, &indx, &flg)); 10243c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUMaxRowNnz, jac->hsolver, indx); } 10253c61a47dSLukas 10263c61a47dSLukas /* ILU: maximum iteration count */ 10273c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_maxiter", "Set ILU max iterations", "None", 0, &indx, &flg)); 10283c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUMaxIter, jac->hsolver, indx); } 10293c61a47dSLukas 10303c61a47dSLukas /* ILU: drop threshold */ 10313c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_ilu_drop_tol", "Drop tolerance for ILU", "None", 0, &tmpdbl, &flg)); 10323c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUDroptol, jac->hsolver, tmpdbl); } 10333c61a47dSLukas 10343c61a47dSLukas /* ILU: Triangular Solve */ 10353c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_ilu_tri_solve", "Enable triangular solve", "None", PETSC_FALSE, &tmp_truth, &flg)); 10363c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUTriSolve, jac->hsolver, tmp_truth); } 10373c61a47dSLukas 10383c61a47dSLukas /* ILU: Lower Jacobi iteration */ 10393c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_lower_jacobi_iters", "Set lower Jacobi iteration count", "None", 0, &indx, &flg)); 10403c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILULowerJacobiIters, jac->hsolver, indx); } 10413c61a47dSLukas 10423c61a47dSLukas /* ILU: Upper Jacobi iteration */ 10433c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_upper_jacobi_iters", "Set upper Jacobi iteration count", "None", 0, &indx, &flg)); 10443c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILUUpperJacobiIters, jac->hsolver, indx); } 10453c61a47dSLukas 10463c61a47dSLukas /* ILU: local reordering */ 10473c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_ilu_local_reordering", "Enable local reordering", "None", PETSC_FALSE, &tmp_truth, &flg)); 10483c61a47dSLukas if (flg) { PetscCallExternal(HYPRE_BoomerAMGSetILULocalReordering, jac->hsolver, tmp_truth); } 10493c61a47dSLukas 10501810e44eSEike Mueller /* Number of levels for ILU(k) for Euclid */ 10519566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level", "Number of levels for ILU(k) in Euclid smoother", "None", 0, &indx, &flg)); 10523c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 10531810e44eSEike Mueller jac->eu_level = indx; 1054792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, indx); 10551810e44eSEike Mueller } 10561810e44eSEike Mueller 10571810e44eSEike Mueller /* Filter for ILU(k) for Euclid */ 105873dcfd97SStefano Zampini PetscReal droptolerance; 10599566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance", "Drop tolerance for ILU(k) in Euclid smoother", "None", 0, &droptolerance, &flg)); 10603c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 10611810e44eSEike Mueller jac->eu_droptolerance = droptolerance; 1062792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, droptolerance); 10631810e44eSEike Mueller } 10641810e44eSEike Mueller 10651810e44eSEike Mueller /* Use Block Jacobi ILUT for Euclid */ 10669566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg)); 10673c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 10681810e44eSEike Mueller jac->eu_bj = tmp_truth; 1069792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuBJ, jac->hsolver, jac->eu_bj); 10701810e44eSEike Mueller } 10711810e44eSEike Mueller 107216d9e3a6SLisandro Dalcin /* Relax type */ 1073dd39110bSPierre 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)); 107416d9e3a6SLisandro Dalcin if (flg) { 10750f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 1076792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, indx); 10770f1074feSSatish Balay /* by default, coarse type set to 9 */ 10780f1074feSSatish Balay jac->relaxtype[2] = 9; 1079792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, 9, 3); 108016d9e3a6SLisandro Dalcin } 1081dd39110bSPierre 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)); 108216d9e3a6SLisandro Dalcin if (flg) { 108316d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 1084792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 1); 108516d9e3a6SLisandro Dalcin } 1086dd39110bSPierre 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)); 108716d9e3a6SLisandro Dalcin if (flg) { 10880f1074feSSatish Balay jac->relaxtype[1] = indx; 1089792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 2); 109016d9e3a6SLisandro Dalcin } 1091dd39110bSPierre 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)); 109216d9e3a6SLisandro Dalcin if (flg) { 10930f1074feSSatish Balay jac->relaxtype[2] = indx; 1094792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 3); 109516d9e3a6SLisandro Dalcin } 109616d9e3a6SLisandro Dalcin 109716d9e3a6SLisandro Dalcin /* Relaxation Weight */ 10989566063dSJacob 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)); 109916d9e3a6SLisandro Dalcin if (flg) { 1100792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxWt, jac->hsolver, tmpdbl); 110116d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 110216d9e3a6SLisandro Dalcin } 110316d9e3a6SLisandro Dalcin 110416d9e3a6SLisandro Dalcin n = 2; 110516d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 11069566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level", "Set the relaxation weight for a particular level (weight,level)", "None", twodbl, &n, &flg)); 110716d9e3a6SLisandro Dalcin if (flg) { 11080fdf79fbSJacob 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); 110916d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 1110792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelRelaxWt, jac->hsolver, twodbl[0], indx); 111116d9e3a6SLisandro Dalcin } 111216d9e3a6SLisandro Dalcin 111316d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 11149566063dSJacob 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)); 111516d9e3a6SLisandro Dalcin if (flg) { 1116792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOuterWt, jac->hsolver, tmpdbl); 111716d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 111816d9e3a6SLisandro Dalcin } 111916d9e3a6SLisandro Dalcin 112016d9e3a6SLisandro Dalcin n = 2; 112116d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 11229566063dSJacob 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)); 112316d9e3a6SLisandro Dalcin if (flg) { 11240fdf79fbSJacob 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); 112516d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 1126792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelOuterWt, jac->hsolver, twodbl[0], indx); 112716d9e3a6SLisandro Dalcin } 112816d9e3a6SLisandro Dalcin 112916d9e3a6SLisandro Dalcin /* the Relax Order */ 11309566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg)); 113116d9e3a6SLisandro Dalcin 11328afaa268SBarry Smith if (flg && tmp_truth) { 113316d9e3a6SLisandro Dalcin jac->relaxorder = 0; 1134792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 113516d9e3a6SLisandro Dalcin } 1136dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type", "Measure type", "None", HYPREBoomerAMGMeasureType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType), HYPREBoomerAMGMeasureType[0], &indx, &flg)); 113716d9e3a6SLisandro Dalcin if (flg) { 113816d9e3a6SLisandro Dalcin jac->measuretype = indx; 1139792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 114016d9e3a6SLisandro Dalcin } 11410f1074feSSatish Balay /* update list length 3/07 */ 1142dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type", "Coarsen type", "None", HYPREBoomerAMGCoarsenType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType), HYPREBoomerAMGCoarsenType[6], &indx, &flg)); 114316d9e3a6SLisandro Dalcin if (flg) { 114416d9e3a6SLisandro Dalcin jac->coarsentype = indx; 1145792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 114616d9e3a6SLisandro Dalcin } 11470f1074feSSatish Balay 11489566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg)); 114948a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 11509566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg)); 115148a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 1152db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 1153db6f9c32SMark Adams // global parameter but is closely associated with BoomerAMG 1154dd39110bSPierre 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)); 11552d6c3ceeSStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1156db6f9c32SMark Adams if (!flg) indx = 0; 11579566063dSJacob Faibussowitsch PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, PCHYPRESpgemmTypes[indx])); 11582d6c3ceeSStefano Zampini #else 11592d6c3ceeSStefano Zampini PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, "hypre")); 11602d6c3ceeSStefano Zampini #endif 1161db6f9c32SMark Adams #endif 1162589dcaf0SStefano Zampini /* AIR */ 1163589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 11649566063dSJacob 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)); 1165792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 1166589dcaf0SStefano Zampini if (jac->Rtype) { 116719be502cSAlexander HYPRE_Int **grid_relax_points = hypre_TAlloc(HYPRE_Int *, 4, HYPRE_MEMORY_HOST); 116819be502cSAlexander char *prerelax[256]; 116919be502cSAlexander char *postrelax[256]; 117019be502cSAlexander char stringF[2] = "F", stringC[2] = "C", stringA[2] = "A"; 117119be502cSAlexander PetscInt ns_down = 256, ns_up = 256; 117219be502cSAlexander PetscBool matchF, matchC, matchA; 117319be502cSAlexander 1174589dcaf0SStefano 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 */ 1175589dcaf0SStefano Zampini 11769566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR", "Threshold for R", "None", jac->Rstrongthreshold, &jac->Rstrongthreshold, NULL)); 1177792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 1178589dcaf0SStefano Zampini 11799566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR", "Filter threshold for R", "None", jac->Rfilterthreshold, &jac->Rfilterthreshold, NULL)); 1180792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 1181589dcaf0SStefano Zampini 11829566063dSJacob 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)); 1183792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 1184589dcaf0SStefano Zampini 11859566063dSJacob 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)); 1186792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 118719be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_prerelax", "Defines prerelax scheme", "None", prerelax, &ns_down, NULL)); 118819be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_postrelax", "Defines postrelax scheme", "None", postrelax, &ns_up, NULL)); 118919be502cSAlexander 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"); 119019be502cSAlexander 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"); 119119be502cSAlexander 119219be502cSAlexander grid_relax_points[0] = NULL; 119319be502cSAlexander grid_relax_points[1] = hypre_TAlloc(HYPRE_Int, ns_down, HYPRE_MEMORY_HOST); 119419be502cSAlexander grid_relax_points[2] = hypre_TAlloc(HYPRE_Int, ns_up, HYPRE_MEMORY_HOST); 119519be502cSAlexander grid_relax_points[3] = hypre_TAlloc(HYPRE_Int, jac->gridsweeps[2], HYPRE_MEMORY_HOST); 119619be502cSAlexander grid_relax_points[3][0] = 0; 119719be502cSAlexander 119819be502cSAlexander // set down relax scheme 119919be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) { 120019be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringF, &matchF)); 120119be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringC, &matchC)); 120219be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringA, &matchA)); 120319be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_prerelax are C, F, and A"); 120419be502cSAlexander if (matchF) grid_relax_points[1][i] = -1; 120519be502cSAlexander else if (matchC) grid_relax_points[1][i] = 1; 120619be502cSAlexander else if (matchA) grid_relax_points[1][i] = 0; 120719be502cSAlexander } 120819be502cSAlexander 120919be502cSAlexander // set up relax scheme 121019be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) { 121119be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringF, &matchF)); 121219be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringC, &matchC)); 121319be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringA, &matchA)); 121419be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_postrelax are C, F, and A"); 121519be502cSAlexander if (matchF) grid_relax_points[2][i] = -1; 121619be502cSAlexander else if (matchC) grid_relax_points[2][i] = 1; 121719be502cSAlexander else if (matchA) grid_relax_points[2][i] = 0; 121819be502cSAlexander } 121919be502cSAlexander 122019be502cSAlexander // set coarse relax scheme 122119be502cSAlexander for (PetscInt i = 0; i < jac->gridsweeps[2]; i++) grid_relax_points[3][i] = 0; 122219be502cSAlexander 122319be502cSAlexander // Pass relax schemes to hypre 122419be502cSAlexander PetscCallExternal(HYPRE_BoomerAMGSetGridRelaxPoints, jac->hsolver, grid_relax_points); 122519be502cSAlexander 122619be502cSAlexander // cleanup memory 122719be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) PetscCall(PetscFree(prerelax[i])); 122819be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) PetscCall(PetscFree(postrelax[i])); 1229589dcaf0SStefano Zampini } 1230589dcaf0SStefano Zampini #endif 1231589dcaf0SStefano Zampini 1232ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9, 9, 9) 123363a3b9bcSJacob 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); 1234ecae95adSPierre Jolivet #endif 1235ecae95adSPierre Jolivet 12360f1074feSSatish Balay /* new 3/07 */ 1237dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type", "Interpolation type", "None", HYPREBoomerAMGInterpType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType), HYPREBoomerAMGInterpType[0], &indx, &flg)); 1238589dcaf0SStefano Zampini if (flg || jac->Rtype) { 1239589dcaf0SStefano Zampini if (flg) jac->interptype = indx; 1240792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 12410f1074feSSatish Balay } 12420f1074feSSatish Balay 12439566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", &flg)); 124416d9e3a6SLisandro Dalcin if (flg) { 1245b96a4a96SBarry Smith level = 3; 12469566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", level, &level, NULL)); 12472fa5cd67SKarl Rupp 1248b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1249792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel, jac->hsolver, level); 12502ae77aedSBarry Smith } 12512ae77aedSBarry Smith 12529566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", &flg)); 12532ae77aedSBarry Smith if (flg) { 1254b96a4a96SBarry Smith level = 3; 12559566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", level, &level, NULL)); 12562fa5cd67SKarl Rupp 1257b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1258792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDebugFlag, jac->hsolver, level); 125916d9e3a6SLisandro Dalcin } 12608f87f92bSBarry Smith 12619566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg)); 12628f87f92bSBarry Smith if (flg && tmp_truth) { 12638f87f92bSBarry Smith PetscInt tmp_int; 12649566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", jac->nodal_relax_levels, &tmp_int, &flg)); 12658f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 1266792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, 6); 1267792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDomainType, jac->hsolver, 1); 1268792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOverlap, jac->hsolver, 0); 1269792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, jac->nodal_relax_levels); 12708f87f92bSBarry Smith } 12718f87f92bSBarry Smith 12729566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL)); 1273792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 1274589dcaf0SStefano Zampini 1275589dcaf0SStefano Zampini /* options for ParaSails solvers */ 1276dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flg)); 1277589dcaf0SStefano Zampini if (flg) { 1278589dcaf0SStefano Zampini jac->symt = indx; 1279792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSym, jac->hsolver, jac->symt); 1280589dcaf0SStefano Zampini } 1281589dcaf0SStefano Zampini 1282d0609cedSBarry Smith PetscOptionsHeadEnd(); 12833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 128416d9e3a6SLisandro Dalcin } 128516d9e3a6SLisandro Dalcin 1286d71ae5a4SJacob 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) 1287d71ae5a4SJacob Faibussowitsch { 128816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 12892cf14000SStefano Zampini HYPRE_Int oits; 129016d9e3a6SLisandro Dalcin 129116d9e3a6SLisandro Dalcin PetscFunctionBegin; 12929566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 1293792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, its * jac->maxiter); 1294792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, rtol); 129516d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 12969566063dSJacob Faibussowitsch PetscCall(PCApply_HYPRE(pc, b, y)); 129716d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 1298792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGGetNumIterations, jac->hsolver, &oits); 12994d0a8057SBarry Smith *outits = oits; 13004d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 13014d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1302792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 1303792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 13043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 130516d9e3a6SLisandro Dalcin } 130616d9e3a6SLisandro Dalcin 1307d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc, PetscViewer viewer) 1308d71ae5a4SJacob Faibussowitsch { 130916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 13103c61a47dSLukas hypre_ParAMGData *amg_data = (hypre_ParAMGData *)jac->hsolver; 1311ace3abfcSBarry Smith PetscBool iascii; 13123c61a47dSLukas PetscInt indx; 13133c61a47dSLukas PetscReal val; 131416d9e3a6SLisandro Dalcin 131516d9e3a6SLisandro Dalcin PetscFunctionBegin; 13169566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 131716d9e3a6SLisandro Dalcin if (iascii) { 13189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE BoomerAMG preconditioning\n")); 13199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Cycle type %s\n", HYPREBoomerAMGCycleType[jac->cycletype])); 132063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of levels %" PetscInt_FMT "\n", jac->maxlevels)); 132163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of iterations PER hypre call %" PetscInt_FMT "\n", jac->maxiter)); 13229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Convergence tolerance PER hypre call %g\n", (double)jac->tol)); 13239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for strong coupling %g\n", (double)jac->strongthreshold)); 13249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation truncation factor %g\n", (double)jac->truncfactor)); 132563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: max elements per row %" PetscInt_FMT "\n", jac->pmax)); 132648a46eb9SPierre Jolivet if (jac->interp_refine) PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n", jac->interp_refine)); 132763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of levels of aggressive coarsening %" PetscInt_FMT "\n", jac->agg_nl)); 132863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of paths for aggressive coarsening %" PetscInt_FMT "\n", jac->agg_num_paths)); 13290f1074feSSatish Balay 13309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum row sums %g\n", (double)jac->maxrowsum)); 133116d9e3a6SLisandro Dalcin 133263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps down %" PetscInt_FMT "\n", jac->gridsweeps[0])); 133363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps up %" PetscInt_FMT "\n", jac->gridsweeps[1])); 133463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps on coarse %" PetscInt_FMT "\n", jac->gridsweeps[2])); 133516d9e3a6SLisandro Dalcin 13369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax down %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[0]])); 13379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax up %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[1]])); 13389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax on coarse %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[2]])); 133916d9e3a6SLisandro Dalcin 13409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax weight (all) %g\n", (double)jac->relaxweight)); 13419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Outer relax weight (all) %g\n", (double)jac->outerrelaxweight)); 134216d9e3a6SLisandro Dalcin 134319be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum size of coarsest grid %" PetscInt_FMT "\n", jac->maxc)); 134419be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Minimum size of coarsest grid %" PetscInt_FMT "\n", jac->minc)); 134519be502cSAlexander 134616d9e3a6SLisandro Dalcin if (jac->relaxorder) { 13479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using CF-relaxation\n")); 134816d9e3a6SLisandro Dalcin } else { 13499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using CF-relaxation\n")); 135016d9e3a6SLisandro Dalcin } 13516a251517SEike Mueller if (jac->smoothtype != -1) { 13529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth type %s\n", HYPREBoomerAMGSmoothType[jac->smoothtype])); 135363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num levels %" PetscInt_FMT "\n", jac->smoothnumlevels)); 13543c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num sweeps %" PetscInt_FMT "\n", jac->smoothsweeps)); 13553c61a47dSLukas if (jac->smoothtype == 0) { 13563c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUType", indx = hypre_ParAMGDataILUType(amg_data)); 13573c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU type %s (%" PetscInt_FMT ")\n", HYPREILUType[indx], indx)); 13583c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULevel", indx = hypre_ParAMGDataILULevel(amg_data)); 13593c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU level %" PetscInt_FMT "\n", indx)); 13603c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUMaxIter", indx = hypre_ParAMGDataILUMaxIter(amg_data)); 13613c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max iterations %" PetscInt_FMT "\n", indx)); 13623c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUMaxRowNnz", indx = hypre_ParAMGDataILUMaxRowNnz(amg_data)); 13633c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max NNZ per row %" PetscInt_FMT "\n", indx)); 13643c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUTriSolve", indx = hypre_ParAMGDataILUTriSolve(amg_data)); 13653c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU triangular solve %" PetscInt_FMT "\n", indx)); 13663c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataTol", val = hypre_ParAMGDataTol(amg_data)); 13673c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU tolerance %e\n", val)); 13683c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUDroptol", val = hypre_ParAMGDataILUDroptol(amg_data)); 13693c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU drop tolerance %e\n", val)); 13703c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULocalReordering", indx = hypre_ParAMGDataILULocalReordering(amg_data)); 13713c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU local reordering %" PetscInt_FMT "\n", indx)); 13723c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULowerJacobiIters", indx = hypre_ParAMGDataILULowerJacobiIters(amg_data)); 13733c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU lower Jacobi iterations %" PetscInt_FMT "\n", indx)); 13743c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUUpperJacobiIters", indx = hypre_ParAMGDataILUUpperJacobiIters(amg_data)); 13753c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU upper Jacobi iterations %" PetscInt_FMT "\n", indx)); 13763c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataPrintLevel", indx = hypre_ParAMGDataPrintLevel(amg_data)); 13773c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU print level %" PetscInt_FMT "\n", indx)); 13783c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataLogging", indx = hypre_ParAMGDataLogging(amg_data)); 13793c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU logging level %" PetscInt_FMT "\n", indx)); 13803c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupType", indx = hypre_ParAMGDataILUIterSetupType(amg_data)); 13813c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup type %s (%" PetscInt_FMT ")\n", HYPREILUIterSetup[indx], indx)); 13823c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupOption", indx = hypre_ParAMGDataILUIterSetupOption(amg_data)); 13833c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup option %" PetscInt_FMT "\n", indx)); 13843c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupMaxIter", indx = hypre_ParAMGDataILUIterSetupMaxIter(amg_data)); 13853c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup max iterations %" PetscInt_FMT "\n", indx)); 13863c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupTolerance", val = hypre_ParAMGDataILUIterSetupTolerance(amg_data)); 13873c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup tolerance %e\n", val)); 13883c61a47dSLukas } 13897e352d70SEike Mueller } else { 13909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using more complex smoothers.\n")); 13911810e44eSEike Mueller } 13921810e44eSEike Mueller if (jac->smoothtype == 3) { 139363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) levels %" PetscInt_FMT "\n", jac->eu_level)); 13949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) drop tolerance %g\n", (double)jac->eu_droptolerance)); 139563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 13966a251517SEike Mueller } 13979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Measure type %s\n", HYPREBoomerAMGMeasureType[jac->measuretype])); 13989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Coarsen type %s\n", HYPREBoomerAMGCoarsenType[jac->coarsentype])); 13999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation type %s\n", jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt")); 140048a46eb9SPierre Jolivet if (jac->nodal_coarsening) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n", jac->nodal_coarsening)); 14015272c319SBarry Smith if (jac->vec_interp_variant) { 140263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n", jac->vec_interp_variant)); 140363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n", jac->vec_interp_qmax)); 14049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n", jac->vec_interp_smooth)); 14058f87f92bSBarry Smith } 140648a46eb9SPierre Jolivet if (jac->nodal_relax) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n", jac->nodal_relax_levels)); 1407db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 14089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", jac->spgemm_type)); 14092d6c3ceeSStefano Zampini #else 14102d6c3ceeSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", "hypre")); 1411db6f9c32SMark Adams #endif 1412589dcaf0SStefano Zampini /* AIR */ 1413589dcaf0SStefano Zampini if (jac->Rtype) { 141463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using approximate ideal restriction type %" PetscInt_FMT "\n", jac->Rtype)); 14159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for R %g\n", (double)jac->Rstrongthreshold)); 14169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Filter for R %g\n", (double)jac->Rfilterthreshold)); 14179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop tolerance %g\n", (double)jac->Adroptol)); 141863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop type %" PetscInt_FMT "\n", jac->Adroptype)); 1419589dcaf0SStefano Zampini } 142016d9e3a6SLisandro Dalcin } 14213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 142216d9e3a6SLisandro Dalcin } 142316d9e3a6SLisandro Dalcin 1424d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc, PetscOptionItems *PetscOptionsObject) 1425d71ae5a4SJacob Faibussowitsch { 142616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 14274ddd07fcSJed Brown PetscInt indx; 1428ace3abfcSBarry Smith PetscBool flag; 142916d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 143016d9e3a6SLisandro Dalcin 143116d9e3a6SLisandro Dalcin PetscFunctionBegin; 1432d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ParaSails Options"); 14339566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels", "Number of number of levels", "None", jac->nlevels, &jac->nlevels, 0)); 14349566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh", "Threshold", "None", jac->threshold, &jac->threshold, &flag)); 1435792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 143616d9e3a6SLisandro Dalcin 14379566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter", "filter", "None", jac->filter, &jac->filter, &flag)); 1438792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 143916d9e3a6SLisandro Dalcin 14409566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal", "Load balance", "None", jac->loadbal, &jac->loadbal, &flag)); 1441792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 144216d9e3a6SLisandro Dalcin 14439566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging", "Print info to screen", "None", (PetscBool)jac->logging, (PetscBool *)&jac->logging, &flag)); 1444792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 144516d9e3a6SLisandro Dalcin 14469566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse", "Reuse nonzero pattern in preconditioner", "None", (PetscBool)jac->ruse, (PetscBool *)&jac->ruse, &flag)); 1447792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 144816d9e3a6SLisandro Dalcin 1449dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flag)); 145016d9e3a6SLisandro Dalcin if (flag) { 145116d9e3a6SLisandro Dalcin jac->symt = indx; 1452792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 145316d9e3a6SLisandro Dalcin } 145416d9e3a6SLisandro Dalcin 1455d0609cedSBarry Smith PetscOptionsHeadEnd(); 14563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 145716d9e3a6SLisandro Dalcin } 145816d9e3a6SLisandro Dalcin 1459d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ParaSails(PC pc, PetscViewer viewer) 1460d71ae5a4SJacob Faibussowitsch { 146116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1462ace3abfcSBarry Smith PetscBool iascii; 1463feb237baSPierre Jolivet const char *symt = 0; 146416d9e3a6SLisandro Dalcin 146516d9e3a6SLisandro Dalcin PetscFunctionBegin; 14669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 146716d9e3a6SLisandro Dalcin if (iascii) { 14689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ParaSails preconditioning\n")); 146963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " nlevels %" PetscInt_FMT "\n", jac->nlevels)); 14709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " threshold %g\n", (double)jac->threshold)); 14719566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " filter %g\n", (double)jac->filter)); 14729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " load balance %g\n", (double)jac->loadbal)); 14739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " reuse nonzero structure %s\n", PetscBools[jac->ruse])); 14749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " print info to screen %s\n", PetscBools[jac->logging])); 14752fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 14762fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 14772fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 147863a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONG, "Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT, jac->symt); 14799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", symt)); 148016d9e3a6SLisandro Dalcin } 14813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 148216d9e3a6SLisandro Dalcin } 1483f1580f4eSBarry Smith 1484d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc, PetscOptionItems *PetscOptionsObject) 1485d71ae5a4SJacob Faibussowitsch { 14864cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 14874cb006feSStefano Zampini PetscInt n; 14884cb006feSStefano Zampini PetscBool flag, flag2, flag3, flag4; 14894cb006feSStefano Zampini 14904cb006feSStefano Zampini PetscFunctionBegin; 1491d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE AMS Options"); 14929566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level", "Debugging output level for AMS", "None", jac->as_print, &jac->as_print, &flag)); 1493792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 14949566063dSJacob 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)); 1495792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 14969566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type", "Cycle type for AMS multigrid", "None", jac->ams_cycle_type, &jac->ams_cycle_type, &flag)); 1497792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 14989566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_tol", "Error tolerance for AMS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1499792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 15009566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type", "Relaxation type for AMS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 15019566063dSJacob 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)); 15029566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight", "Relaxation weight for AMS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 15039566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_omega", "SSOR coefficient for AMS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 150448a46eb9SPierre 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); 15059566063dSJacob 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)); 15064cb006feSStefano Zampini n = 5; 15079566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options", "AMG options for vector Poisson", "None", jac->as_amg_alpha_opts, &n, &flag2)); 15084cb006feSStefano Zampini if (flag || flag2) { 1509792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1510863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1511863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 15129371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1513a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 15144cb006feSStefano Zampini } 15159566063dSJacob 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)); 15164cb006feSStefano Zampini n = 5; 15179566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options", "AMG options for scalar Poisson solver", "None", jac->as_amg_beta_opts, &n, &flag2)); 15184cb006feSStefano Zampini if (flag || flag2) { 1519792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1520863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1521863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 15229371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1523a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 15244cb006feSStefano Zampini } 15259566063dSJacob 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)); 152623df4f25SStefano Zampini if (flag) { /* override HYPRE's default only if the options is used */ 1527792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetProjectionFrequency, jac->hsolver, jac->ams_proj_freq); 152823df4f25SStefano Zampini } 1529d0609cedSBarry Smith PetscOptionsHeadEnd(); 15303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15314cb006feSStefano Zampini } 15324cb006feSStefano Zampini 1533d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_AMS(PC pc, PetscViewer viewer) 1534d71ae5a4SJacob Faibussowitsch { 15354cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 15364cb006feSStefano Zampini PetscBool iascii; 15374cb006feSStefano Zampini 15384cb006feSStefano Zampini PetscFunctionBegin; 15399566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 15404cb006feSStefano Zampini if (iascii) { 15419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE AMS preconditioning\n")); 154263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 154363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 154463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 154563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 154663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 154763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 154863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 15494cb006feSStefano Zampini if (jac->alpha_Poisson) { 15509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (passed in by user)\n")); 15514cb006feSStefano Zampini } else { 15529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (computed) \n")); 15534cb006feSStefano Zampini } 155463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 155563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 155663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 155763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 155863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 155963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 15604cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 15614cb006feSStefano Zampini if (jac->beta_Poisson) { 15629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (passed in by user)\n")); 15634cb006feSStefano Zampini } else { 15649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (computed) \n")); 15654cb006feSStefano Zampini } 156663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 156763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 156863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 156963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 157063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 157163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_beta_theta)); 157248a46eb9SPierre 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)); 157323df4f25SStefano Zampini } else { 15749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver not used (zero-conductivity everywhere) \n")); 15754cb006feSStefano Zampini } 15764cb006feSStefano Zampini } 15773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15784cb006feSStefano Zampini } 15794cb006feSStefano Zampini 1580d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PC pc, PetscOptionItems *PetscOptionsObject) 1581d71ae5a4SJacob Faibussowitsch { 1582863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1583863406b8SStefano Zampini PetscInt n; 1584863406b8SStefano Zampini PetscBool flag, flag2, flag3, flag4; 1585863406b8SStefano Zampini 1586863406b8SStefano Zampini PetscFunctionBegin; 1587d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ADS Options"); 15889566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level", "Debugging output level for ADS", "None", jac->as_print, &jac->as_print, &flag)); 1589792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 15909566063dSJacob 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)); 1591792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 15929566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type", "Cycle type for ADS multigrid", "None", jac->ads_cycle_type, &jac->ads_cycle_type, &flag)); 1593792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ads_cycle_type); 15949566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_tol", "Error tolerance for ADS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1595792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 15969566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type", "Relaxation type for ADS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 15979566063dSJacob 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)); 15989566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight", "Relaxation weight for ADS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 15999566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_omega", "SSOR coefficient for ADS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 160048a46eb9SPierre 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); 16019566063dSJacob 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)); 1602863406b8SStefano Zampini n = 5; 16039566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options", "AMG options for AMS solver inside ADS", "None", jac->as_amg_alpha_opts, &n, &flag2)); 16049566063dSJacob 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)); 1605863406b8SStefano Zampini if (flag || flag2 || flag3) { 1606792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMS cycle type */ 1607863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1608863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1609863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 16109371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1611a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 1612863406b8SStefano Zampini } 16139566063dSJacob 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)); 1614863406b8SStefano Zampini n = 5; 16159566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options", "AMG options for vector AMG solver inside ADS", "None", jac->as_amg_beta_opts, &n, &flag2)); 1616863406b8SStefano Zampini if (flag || flag2) { 1617792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1618863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1619863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 16209371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1621a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 1622863406b8SStefano Zampini } 1623d0609cedSBarry Smith PetscOptionsHeadEnd(); 16243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1625863406b8SStefano Zampini } 1626863406b8SStefano Zampini 1627d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ADS(PC pc, PetscViewer viewer) 1628d71ae5a4SJacob Faibussowitsch { 1629863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1630863406b8SStefano Zampini PetscBool iascii; 1631863406b8SStefano Zampini 1632863406b8SStefano Zampini PetscFunctionBegin; 16339566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1634863406b8SStefano Zampini if (iascii) { 16359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ADS preconditioning\n")); 163663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 163763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ads_cycle_type)); 163863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 163963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 164063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 164163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 164263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 16439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " AMS solver using boomerAMG\n")); 164463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 164563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 164663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 164763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 164863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 164963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 165063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 16519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver using boomerAMG\n")); 165263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 165363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 165463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 165563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 165663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 165763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_beta_theta)); 1658863406b8SStefano Zampini } 16593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1660863406b8SStefano Zampini } 1661863406b8SStefano Zampini 1662d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G) 1663d71ae5a4SJacob Faibussowitsch { 16644cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 16655ac14e1cSStefano Zampini PetscBool ishypre; 16664cb006feSStefano Zampini 16674cb006feSStefano Zampini PetscFunctionBegin; 16689566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)G, MATHYPRE, &ishypre)); 16695ac14e1cSStefano Zampini if (ishypre) { 16709566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)G)); 16719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 16725ac14e1cSStefano Zampini jac->G = G; 16735ac14e1cSStefano Zampini } else { 16749566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 16759566063dSJacob Faibussowitsch PetscCall(MatConvert(G, MATHYPRE, MAT_INITIAL_MATRIX, &jac->G)); 16765ac14e1cSStefano Zampini } 16773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16784cb006feSStefano Zampini } 16794cb006feSStefano Zampini 16804cb006feSStefano Zampini /*@ 1681f1580f4eSBarry Smith PCHYPRESetDiscreteGradient - Set discrete gradient matrix for `PCHYPRE` type of ams or ads 16824cb006feSStefano Zampini 1683c3339decSBarry Smith Collective 16844cb006feSStefano Zampini 16854cb006feSStefano Zampini Input Parameters: 16864cb006feSStefano Zampini + pc - the preconditioning context 16874cb006feSStefano Zampini - G - the discrete gradient 16884cb006feSStefano Zampini 16894cb006feSStefano Zampini Level: intermediate 16904cb006feSStefano Zampini 169195452b02SPatrick Sanan Notes: 169295452b02SPatrick Sanan G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 1693147403d9SBarry Smith 1694863406b8SStefano 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 16954cb006feSStefano Zampini 1696feefa0e1SJacob Faibussowitsch Developer Notes: 1697f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1698f1580f4eSBarry Smith 1699562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteCurl()` 17004cb006feSStefano Zampini @*/ 1701d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 1702d71ae5a4SJacob Faibussowitsch { 17034cb006feSStefano Zampini PetscFunctionBegin; 17044cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 17054cb006feSStefano Zampini PetscValidHeaderSpecific(G, MAT_CLASSID, 2); 17064cb006feSStefano Zampini PetscCheckSameComm(pc, 1, G, 2); 1707cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteGradient_C", (PC, Mat), (pc, G)); 17083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17094cb006feSStefano Zampini } 17104cb006feSStefano Zampini 1711d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C) 1712d71ae5a4SJacob Faibussowitsch { 1713863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 17145ac14e1cSStefano Zampini PetscBool ishypre; 1715863406b8SStefano Zampini 1716863406b8SStefano Zampini PetscFunctionBegin; 17179566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C, MATHYPRE, &ishypre)); 17185ac14e1cSStefano Zampini if (ishypre) { 17199566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)C)); 17209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 17215ac14e1cSStefano Zampini jac->C = C; 17225ac14e1cSStefano Zampini } else { 17239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 17249566063dSJacob Faibussowitsch PetscCall(MatConvert(C, MATHYPRE, MAT_INITIAL_MATRIX, &jac->C)); 17255ac14e1cSStefano Zampini } 17263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1727863406b8SStefano Zampini } 1728863406b8SStefano Zampini 1729863406b8SStefano Zampini /*@ 17306e415bd2SNuno Nobre PCHYPRESetDiscreteCurl - Set discrete curl matrix for `PCHYPRE` type of ads 1731863406b8SStefano Zampini 1732c3339decSBarry Smith Collective 1733863406b8SStefano Zampini 1734863406b8SStefano Zampini Input Parameters: 1735863406b8SStefano Zampini + pc - the preconditioning context 1736863406b8SStefano Zampini - C - the discrete curl 1737863406b8SStefano Zampini 1738863406b8SStefano Zampini Level: intermediate 1739863406b8SStefano Zampini 174095452b02SPatrick Sanan Notes: 174195452b02SPatrick Sanan C should have as many rows as the number of faces and as many columns as the number of edges in the mesh 1742147403d9SBarry Smith 17436e415bd2SNuno Nobre Each row of C has as many nonzeros as the number of edges of a face, with column indexes being the global indexes of the corresponding edge: matrix entries are +1 and -1 depending on edge orientation with respect to the face orientation 1744863406b8SStefano Zampini 1745feefa0e1SJacob Faibussowitsch Developer Notes: 1746f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1747f1580f4eSBarry Smith 1748f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ads it should be called `PCHYPREADSSetDiscreteCurl()` 1749f1580f4eSBarry Smith 1750562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()` 1751863406b8SStefano Zampini @*/ 1752d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C) 1753d71ae5a4SJacob Faibussowitsch { 1754863406b8SStefano Zampini PetscFunctionBegin; 1755863406b8SStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1756863406b8SStefano Zampini PetscValidHeaderSpecific(C, MAT_CLASSID, 2); 1757863406b8SStefano Zampini PetscCheckSameComm(pc, 1, C, 2); 1758cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteCurl_C", (PC, Mat), (pc, C)); 17593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1760863406b8SStefano Zampini } 1761863406b8SStefano Zampini 1762d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1763d71ae5a4SJacob Faibussowitsch { 17646bf688a0SCe Qin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 17656bf688a0SCe Qin PetscBool ishypre; 17666bf688a0SCe Qin PetscInt i; 17676bf688a0SCe Qin 17684d86920dSPierre Jolivet PetscFunctionBegin; 17699566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 17709566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 17716bf688a0SCe Qin for (i = 0; i < 3; ++i) { 17729566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[i])); 17739566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[i])); 17746bf688a0SCe Qin } 17756bf688a0SCe Qin 17766bf688a0SCe Qin jac->dim = dim; 17776bf688a0SCe Qin if (RT_PiFull) { 17789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_PiFull, MATHYPRE, &ishypre)); 17796bf688a0SCe Qin if (ishypre) { 17809566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_PiFull)); 17816bf688a0SCe Qin jac->RT_PiFull = RT_PiFull; 17826bf688a0SCe Qin } else { 17839566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_PiFull)); 17846bf688a0SCe Qin } 17856bf688a0SCe Qin } 17866bf688a0SCe Qin if (RT_Pi) { 17876bf688a0SCe Qin for (i = 0; i < dim; ++i) { 17886bf688a0SCe Qin if (RT_Pi[i]) { 17899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_Pi[i], MATHYPRE, &ishypre)); 17906bf688a0SCe Qin if (ishypre) { 17919566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_Pi[i])); 17926bf688a0SCe Qin jac->RT_Pi[i] = RT_Pi[i]; 17936bf688a0SCe Qin } else { 17949566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_Pi[i])); 17956bf688a0SCe Qin } 17966bf688a0SCe Qin } 17976bf688a0SCe Qin } 17986bf688a0SCe Qin } 17996bf688a0SCe Qin if (ND_PiFull) { 18009566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_PiFull, MATHYPRE, &ishypre)); 18016bf688a0SCe Qin if (ishypre) { 18029566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_PiFull)); 18036bf688a0SCe Qin jac->ND_PiFull = ND_PiFull; 18046bf688a0SCe Qin } else { 18059566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_PiFull)); 18066bf688a0SCe Qin } 18076bf688a0SCe Qin } 18086bf688a0SCe Qin if (ND_Pi) { 18096bf688a0SCe Qin for (i = 0; i < dim; ++i) { 18106bf688a0SCe Qin if (ND_Pi[i]) { 18119566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_Pi[i], MATHYPRE, &ishypre)); 18126bf688a0SCe Qin if (ishypre) { 18139566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_Pi[i])); 18146bf688a0SCe Qin jac->ND_Pi[i] = ND_Pi[i]; 18156bf688a0SCe Qin } else { 18169566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_Pi[i])); 18176bf688a0SCe Qin } 18186bf688a0SCe Qin } 18196bf688a0SCe Qin } 18206bf688a0SCe Qin } 18213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18226bf688a0SCe Qin } 18236bf688a0SCe Qin 18246bf688a0SCe Qin /*@ 1825f1580f4eSBarry Smith PCHYPRESetInterpolations - Set interpolation matrices for `PCHYPRE` type of ams or ads 18266bf688a0SCe Qin 1827c3339decSBarry Smith Collective 18286bf688a0SCe Qin 18296bf688a0SCe Qin Input Parameters: 18306bf688a0SCe Qin + pc - the preconditioning context 18312fe279fdSBarry Smith . dim - the dimension of the problem, only used in AMS 18322fe279fdSBarry Smith . RT_PiFull - Raviart-Thomas interpolation matrix 18332fe279fdSBarry Smith . RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix 18342fe279fdSBarry Smith . ND_PiFull - Nedelec interpolation matrix 18356bf688a0SCe Qin - ND_Pi - x/y/z component of Nedelec interpolation matrix 18366bf688a0SCe Qin 1837f1580f4eSBarry Smith Level: intermediate 1838f1580f4eSBarry Smith 183995452b02SPatrick Sanan Notes: 184095452b02SPatrick Sanan For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL. 1841147403d9SBarry Smith 18426bf688a0SCe Qin For ADS, both type of interpolation matrices are needed. 1843147403d9SBarry Smith 1844feefa0e1SJacob Faibussowitsch Developer Notes: 1845f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 18466bf688a0SCe Qin 1847562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE` 18486bf688a0SCe Qin @*/ 1849d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1850d71ae5a4SJacob Faibussowitsch { 18516bf688a0SCe Qin PetscInt i; 18526bf688a0SCe Qin 18536bf688a0SCe Qin PetscFunctionBegin; 18546bf688a0SCe Qin PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 18556bf688a0SCe Qin if (RT_PiFull) { 18566bf688a0SCe Qin PetscValidHeaderSpecific(RT_PiFull, MAT_CLASSID, 3); 18576bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_PiFull, 3); 18586bf688a0SCe Qin } 18596bf688a0SCe Qin if (RT_Pi) { 18604f572ea9SToby Isaac PetscAssertPointer(RT_Pi, 4); 18616bf688a0SCe Qin for (i = 0; i < dim; ++i) { 18626bf688a0SCe Qin if (RT_Pi[i]) { 18636bf688a0SCe Qin PetscValidHeaderSpecific(RT_Pi[i], MAT_CLASSID, 4); 18646bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_Pi[i], 4); 18656bf688a0SCe Qin } 18666bf688a0SCe Qin } 18676bf688a0SCe Qin } 18686bf688a0SCe Qin if (ND_PiFull) { 18696bf688a0SCe Qin PetscValidHeaderSpecific(ND_PiFull, MAT_CLASSID, 5); 18706bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_PiFull, 5); 18716bf688a0SCe Qin } 18726bf688a0SCe Qin if (ND_Pi) { 18734f572ea9SToby Isaac PetscAssertPointer(ND_Pi, 6); 18746bf688a0SCe Qin for (i = 0; i < dim; ++i) { 18756bf688a0SCe Qin if (ND_Pi[i]) { 18766bf688a0SCe Qin PetscValidHeaderSpecific(ND_Pi[i], MAT_CLASSID, 6); 18776bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_Pi[i], 6); 18786bf688a0SCe Qin } 18796bf688a0SCe Qin } 18806bf688a0SCe Qin } 1881cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetInterpolations_C", (PC, PetscInt, Mat, Mat[], Mat, Mat[]), (pc, dim, RT_PiFull, RT_Pi, ND_PiFull, ND_Pi)); 18823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18836bf688a0SCe Qin } 18846bf688a0SCe Qin 1885d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha) 1886d71ae5a4SJacob Faibussowitsch { 18874cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 18885ac14e1cSStefano Zampini PetscBool ishypre; 18894cb006feSStefano Zampini 18904cb006feSStefano Zampini PetscFunctionBegin; 18919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 18925ac14e1cSStefano Zampini if (ishypre) { 18935ac14e1cSStefano Zampini if (isalpha) { 18949566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 18959566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 18965ac14e1cSStefano Zampini jac->alpha_Poisson = A; 18975ac14e1cSStefano Zampini } else { 18985ac14e1cSStefano Zampini if (A) { 18999566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 19005ac14e1cSStefano Zampini } else { 19015ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 19025ac14e1cSStefano Zampini } 19039566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 19045ac14e1cSStefano Zampini jac->beta_Poisson = A; 19055ac14e1cSStefano Zampini } 19065ac14e1cSStefano Zampini } else { 19075ac14e1cSStefano Zampini if (isalpha) { 19089566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 19099566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->alpha_Poisson)); 19105ac14e1cSStefano Zampini } else { 19115ac14e1cSStefano Zampini if (A) { 19129566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 19139566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->beta_Poisson)); 19145ac14e1cSStefano Zampini } else { 19159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 19165ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 19175ac14e1cSStefano Zampini } 19185ac14e1cSStefano Zampini } 19195ac14e1cSStefano Zampini } 19203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19214cb006feSStefano Zampini } 19224cb006feSStefano Zampini 19234cb006feSStefano Zampini /*@ 1924f1580f4eSBarry Smith PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix for `PCHYPRE` of type ams 19254cb006feSStefano Zampini 1926c3339decSBarry Smith Collective 19274cb006feSStefano Zampini 19284cb006feSStefano Zampini Input Parameters: 19294cb006feSStefano Zampini + pc - the preconditioning context 19304cb006feSStefano Zampini - A - the matrix 19314cb006feSStefano Zampini 19324cb006feSStefano Zampini Level: intermediate 19334cb006feSStefano Zampini 1934f1580f4eSBarry Smith Note: 193595452b02SPatrick Sanan A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 19364cb006feSStefano Zampini 1937feefa0e1SJacob Faibussowitsch Developer Notes: 1938f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1939f1580f4eSBarry Smith 1940f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetAlphaPoissonMatrix()` 1941f1580f4eSBarry Smith 1942562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()` 19434cb006feSStefano Zampini @*/ 1944d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 1945d71ae5a4SJacob Faibussowitsch { 19464cb006feSStefano Zampini PetscFunctionBegin; 19474cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 19484cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 19494cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 1950cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_TRUE)); 19513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19524cb006feSStefano Zampini } 19534cb006feSStefano Zampini 19544cb006feSStefano Zampini /*@ 1955f1580f4eSBarry Smith PCHYPRESetBetaPoissonMatrix - Set Poisson matrix for `PCHYPRE` of type ams 19564cb006feSStefano Zampini 1957c3339decSBarry Smith Collective 19584cb006feSStefano Zampini 19594cb006feSStefano Zampini Input Parameters: 19604cb006feSStefano Zampini + pc - the preconditioning context 1961f1580f4eSBarry Smith - A - the matrix, or NULL to turn it off 19624cb006feSStefano Zampini 19634cb006feSStefano Zampini Level: intermediate 19644cb006feSStefano Zampini 1965f1580f4eSBarry Smith Note: 196695452b02SPatrick Sanan A should be obtained by discretizing the Poisson problem with linear finite elements. 19674cb006feSStefano Zampini 1968feefa0e1SJacob Faibussowitsch Developer Notes: 1969f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1970f1580f4eSBarry Smith 1971f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSPCHYPRESetBetaPoissonMatrix()` 1972f1580f4eSBarry Smith 1973562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 19744cb006feSStefano Zampini @*/ 1975d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 1976d71ae5a4SJacob Faibussowitsch { 19774cb006feSStefano Zampini PetscFunctionBegin; 19784cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 19794cb006feSStefano Zampini if (A) { 19804cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 19814cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 19824cb006feSStefano Zampini } 1983cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_FALSE)); 19843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19854cb006feSStefano Zampini } 19864cb006feSStefano Zampini 1987d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc, Vec ozz, Vec zoz, Vec zzo) 1988d71ae5a4SJacob Faibussowitsch { 19894cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 19904cb006feSStefano Zampini 19914cb006feSStefano Zampini PetscFunctionBegin; 19924cb006feSStefano Zampini /* throw away any vector if already set */ 19939566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 19949566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 19959566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 19969566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(ozz->map, &jac->constants[0])); 19979566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(ozz, jac->constants[0])); 19989566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zoz->map, &jac->constants[1])); 19999566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zoz, jac->constants[1])); 20005ac14e1cSStefano Zampini jac->dim = 2; 20014cb006feSStefano Zampini if (zzo) { 20029566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zzo->map, &jac->constants[2])); 20039566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zzo, jac->constants[2])); 20045ac14e1cSStefano Zampini jac->dim++; 20054cb006feSStefano Zampini } 20063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20074cb006feSStefano Zampini } 20084cb006feSStefano Zampini 20094cb006feSStefano Zampini /*@ 2010f1580f4eSBarry Smith PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis for `PCHYPRE` of type ams 20114cb006feSStefano Zampini 2012c3339decSBarry Smith Collective 20134cb006feSStefano Zampini 20144cb006feSStefano Zampini Input Parameters: 20154cb006feSStefano Zampini + pc - the preconditioning context 20162fe279fdSBarry Smith . ozz - vector representing (1,0,0) (or (1,0) in 2D) 20172fe279fdSBarry Smith . zoz - vector representing (0,1,0) (or (0,1) in 2D) 20184cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 20194cb006feSStefano Zampini 20204cb006feSStefano Zampini Level: intermediate 20214cb006feSStefano Zampini 2022feefa0e1SJacob Faibussowitsch Developer Notes: 2023f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetEdgeConstantVectors()` 2024f1580f4eSBarry Smith 2025562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 20264cb006feSStefano Zampini @*/ 2027d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 2028d71ae5a4SJacob Faibussowitsch { 20294cb006feSStefano Zampini PetscFunctionBegin; 20304cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 20314cb006feSStefano Zampini PetscValidHeaderSpecific(ozz, VEC_CLASSID, 2); 20324cb006feSStefano Zampini PetscValidHeaderSpecific(zoz, VEC_CLASSID, 3); 20334cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo, VEC_CLASSID, 4); 20344cb006feSStefano Zampini PetscCheckSameComm(pc, 1, ozz, 2); 20354cb006feSStefano Zampini PetscCheckSameComm(pc, 1, zoz, 3); 20364cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc, 1, zzo, 4); 2037cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetEdgeConstantVectors_C", (PC, Vec, Vec, Vec), (pc, ozz, zoz, zzo)); 20383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20394cb006feSStefano Zampini } 20404cb006feSStefano Zampini 2041d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREAMSSetInteriorNodes_HYPRE(PC pc, Vec interior) 2042d71ae5a4SJacob Faibussowitsch { 2043be14dc20SKerry Key PC_HYPRE *jac = (PC_HYPRE *)pc->data; 2044be14dc20SKerry Key 2045be14dc20SKerry Key PetscFunctionBegin; 2046be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 2047be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCreate(interior->map, &jac->interior)); 2048be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCopy(interior, jac->interior)); 2049be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_TRUE; 20503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2051be14dc20SKerry Key } 2052be14dc20SKerry Key 2053be14dc20SKerry Key /*@ 2054f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes - Set the list of interior nodes to a zero-conductivity region for `PCHYPRE` of type ams 2055be14dc20SKerry Key 2056c3339decSBarry Smith Collective 2057be14dc20SKerry Key 2058be14dc20SKerry Key Input Parameters: 2059be14dc20SKerry Key + pc - the preconditioning context 2060be14dc20SKerry Key - interior - vector. node is interior if its entry in the array is 1.0. 2061be14dc20SKerry Key 2062be14dc20SKerry Key Level: intermediate 2063be14dc20SKerry Key 2064be14dc20SKerry Key Note: 2065f1580f4eSBarry Smith This calls `HYPRE_AMSSetInteriorNodes()` 2066f1580f4eSBarry Smith 2067562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 2068be14dc20SKerry Key @*/ 2069d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREAMSSetInteriorNodes(PC pc, Vec interior) 2070d71ae5a4SJacob Faibussowitsch { 2071be14dc20SKerry Key PetscFunctionBegin; 2072be14dc20SKerry Key PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2073be14dc20SKerry Key PetscValidHeaderSpecific(interior, VEC_CLASSID, 2); 2074be14dc20SKerry Key PetscCheckSameComm(pc, 1, interior, 2); 2075be14dc20SKerry Key PetscTryMethod(pc, "PCHYPREAMSSetInteriorNodes_C", (PC, Vec), (pc, interior)); 20763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2077be14dc20SKerry Key } 2078be14dc20SKerry Key 2079d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2080d71ae5a4SJacob Faibussowitsch { 20814cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 20824cb006feSStefano Zampini Vec tv; 20834cb006feSStefano Zampini PetscInt i; 20844cb006feSStefano Zampini 20854cb006feSStefano Zampini PetscFunctionBegin; 20864cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 20879566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 20889566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 20899566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 20905ac14e1cSStefano Zampini jac->dim = dim; 20915ac14e1cSStefano Zampini 20924cb006feSStefano Zampini /* compute IJ vector for coordinates */ 20939566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)pc), &tv)); 20949566063dSJacob Faibussowitsch PetscCall(VecSetType(tv, VECSTANDARD)); 20959566063dSJacob Faibussowitsch PetscCall(VecSetSizes(tv, nloc, PETSC_DECIDE)); 20964cb006feSStefano Zampini for (i = 0; i < dim; i++) { 20974cb006feSStefano Zampini PetscScalar *array; 20984cb006feSStefano Zampini PetscInt j; 20994cb006feSStefano Zampini 21009566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(tv->map, &jac->coords[i])); 21019566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(tv, &array)); 21026ea7df73SStefano Zampini for (j = 0; j < nloc; j++) array[j] = coords[j * dim + i]; 21039566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(tv, &array)); 21049566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(tv, jac->coords[i])); 21054cb006feSStefano Zampini } 21069566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tv)); 21073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21084cb006feSStefano Zampini } 21094cb006feSStefano Zampini 2110d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREGetType_HYPRE(PC pc, const char *name[]) 2111d71ae5a4SJacob Faibussowitsch { 211216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 211316d9e3a6SLisandro Dalcin 211416d9e3a6SLisandro Dalcin PetscFunctionBegin; 211516d9e3a6SLisandro Dalcin *name = jac->hypre_type; 21163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 211716d9e3a6SLisandro Dalcin } 211816d9e3a6SLisandro Dalcin 2119d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetType_HYPRE(PC pc, const char name[]) 2120d71ae5a4SJacob Faibussowitsch { 212116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 2122ace3abfcSBarry Smith PetscBool flag; 212316d9e3a6SLisandro Dalcin 212416d9e3a6SLisandro Dalcin PetscFunctionBegin; 212516d9e3a6SLisandro Dalcin if (jac->hypre_type) { 21269566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, name, &flag)); 21275f80ce2aSJacob Faibussowitsch PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "Cannot reset the HYPRE preconditioner type once it has been set"); 21283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212916d9e3a6SLisandro Dalcin } else { 21309566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->hypre_type)); 213116d9e3a6SLisandro Dalcin } 213216d9e3a6SLisandro Dalcin 213316d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 213416d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 213516d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 213616d9e3a6SLisandro Dalcin 21373c61a47dSLukas PetscCall(PetscStrcmp("ilu", jac->hypre_type, &flag)); 21383c61a47dSLukas if (flag) { 21393c61a47dSLukas PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 21403c61a47dSLukas PetscCallExternal(HYPRE_ILUCreate, &jac->hsolver); 21413c61a47dSLukas pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ILU; 21423c61a47dSLukas pc->ops->view = PCView_HYPRE_ILU; 21433c61a47dSLukas jac->destroy = HYPRE_ILUDestroy; 21443c61a47dSLukas jac->setup = HYPRE_ILUSetup; 21453c61a47dSLukas jac->solve = HYPRE_ILUSolve; 21463c61a47dSLukas jac->factorrowsize = PETSC_DEFAULT; 21473c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 21483c61a47dSLukas } 21493c61a47dSLukas 21509566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("pilut", jac->hypre_type, &flag)); 215116d9e3a6SLisandro Dalcin if (flag) { 21529566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2153792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRPilutCreate, jac->comm_hypre, &jac->hsolver); 215416d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 215516d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 215616d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 215716d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 215816d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 215916d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 21603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 216116d9e3a6SLisandro Dalcin } 21629566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("euclid", jac->hypre_type, &flag)); 2163db966c6cSHong Zhang if (flag) { 21644e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 21657de69702SBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Hypre Euclid does not support 64-bit indices"); 21668bf83915SBarry Smith #endif 21679566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2168792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidCreate, jac->comm_hypre, &jac->hsolver); 2169db966c6cSHong Zhang pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 2170db966c6cSHong Zhang pc->ops->view = PCView_HYPRE_Euclid; 2171db966c6cSHong Zhang jac->destroy = HYPRE_EuclidDestroy; 2172db966c6cSHong Zhang jac->setup = HYPRE_EuclidSetup; 2173db966c6cSHong Zhang jac->solve = HYPRE_EuclidSolve; 2174db966c6cSHong Zhang jac->factorrowsize = PETSC_DEFAULT; 2175db966c6cSHong Zhang jac->eu_level = PETSC_DEFAULT; /* default */ 21763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2177db966c6cSHong Zhang } 21789566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("parasails", jac->hypre_type, &flag)); 217916d9e3a6SLisandro Dalcin if (flag) { 21809566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2181792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsCreate, jac->comm_hypre, &jac->hsolver); 218216d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 218316d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 218416d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 218516d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 218616d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 218716d9e3a6SLisandro Dalcin /* initialize */ 218816d9e3a6SLisandro Dalcin jac->nlevels = 1; 21898966356dSPierre Jolivet jac->threshold = .1; 219016d9e3a6SLisandro Dalcin jac->filter = .1; 219116d9e3a6SLisandro Dalcin jac->loadbal = 0; 21922fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int)PETSC_TRUE; 21932fa5cd67SKarl Rupp else jac->logging = (int)PETSC_FALSE; 21942fa5cd67SKarl Rupp 219516d9e3a6SLisandro Dalcin jac->ruse = (int)PETSC_FALSE; 219616d9e3a6SLisandro Dalcin jac->symt = 0; 2197792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 2198792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 2199792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 2200792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 2201792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 2202792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 22033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 220416d9e3a6SLisandro Dalcin } 22059566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("boomeramg", jac->hypre_type, &flag)); 220616d9e3a6SLisandro Dalcin if (flag) { 2207792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGCreate, &jac->hsolver); 220816d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 220916d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 221016d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 221116d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 221285245615SPierre Jolivet pc->ops->matapply = PCMatApply_HYPRE_BoomerAMG; 22139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", PCGetInterpolations_BoomerAMG)); 22149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", PCGetCoarseOperators_BoomerAMG)); 221516d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 221616d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 221716d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 221816d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 221916d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 222016d9e3a6SLisandro Dalcin jac->cycletype = 1; 222116d9e3a6SLisandro Dalcin jac->maxlevels = 25; 222216d9e3a6SLisandro Dalcin jac->maxiter = 1; 22238f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 222416d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 222516d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 222616d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 222716d9e3a6SLisandro Dalcin jac->coarsentype = 6; 222816d9e3a6SLisandro Dalcin jac->measuretype = 0; 22290f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 22306a251517SEike Mueller jac->smoothtype = -1; /* Not set by default */ 2231b9eb5777SEike Mueller jac->smoothnumlevels = 25; 22321810e44eSEike Mueller jac->eu_level = 0; 22331810e44eSEike Mueller jac->eu_droptolerance = 0; 22341810e44eSEike Mueller jac->eu_bj = 0; 2235589dcaf0SStefano Zampini jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */ 22360f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 223716d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 223816d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 223916d9e3a6SLisandro Dalcin jac->relaxorder = 1; 22400f1074feSSatish Balay jac->interptype = 0; 2241589dcaf0SStefano Zampini jac->Rtype = 0; 2242589dcaf0SStefano Zampini jac->Rstrongthreshold = 0.25; 2243589dcaf0SStefano Zampini jac->Rfilterthreshold = 0.0; 2244589dcaf0SStefano Zampini jac->Adroptype = -1; 2245589dcaf0SStefano Zampini jac->Adroptol = 0.0; 22460f1074feSSatish Balay jac->agg_nl = 0; 22476ea7df73SStefano Zampini jac->agg_interptype = 4; 22480f1074feSSatish Balay jac->pmax = 0; 22490f1074feSSatish Balay jac->truncfactor = 0.0; 22500f1074feSSatish Balay jac->agg_num_paths = 1; 2251589dcaf0SStefano Zampini jac->maxc = 9; 2252589dcaf0SStefano Zampini jac->minc = 1; 225322e51d31SStefano Zampini jac->nodal_coarsening = 0; 225422e51d31SStefano Zampini jac->nodal_coarsening_diag = 0; 225522e51d31SStefano Zampini jac->vec_interp_variant = 0; 225622e51d31SStefano Zampini jac->vec_interp_qmax = 0; 225722e51d31SStefano Zampini jac->vec_interp_smooth = PETSC_FALSE; 225822e51d31SStefano Zampini jac->interp_refine = 0; 22598f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 22608f87f92bSBarry Smith jac->nodal_relax_levels = 1; 22616ea7df73SStefano Zampini jac->rap2 = 0; 22626ea7df73SStefano Zampini 22636ea7df73SStefano Zampini /* GPU defaults 22646ea7df73SStefano Zampini from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options 22656ea7df73SStefano Zampini and /src/parcsr_ls/par_amg.c */ 22666ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 22676ea7df73SStefano Zampini jac->keeptranspose = PETSC_TRUE; 22686ea7df73SStefano Zampini jac->mod_rap2 = 1; 22696ea7df73SStefano Zampini jac->coarsentype = 8; 22706ea7df73SStefano Zampini jac->relaxorder = 0; 22716ea7df73SStefano Zampini jac->interptype = 6; 22726ea7df73SStefano Zampini jac->relaxtype[0] = 18; 22736ea7df73SStefano Zampini jac->relaxtype[1] = 18; 22746ea7df73SStefano Zampini jac->agg_interptype = 7; 22756ea7df73SStefano Zampini #else 22766ea7df73SStefano Zampini jac->keeptranspose = PETSC_FALSE; 22776ea7df73SStefano Zampini jac->mod_rap2 = 0; 22786ea7df73SStefano Zampini #endif 2279792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 2280792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 2281792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 2282792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 2283792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 2284792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 2285792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 2286792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 2287792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 2288792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 2289792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 2290792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 2291792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggInterpType, jac->hsolver, jac->agg_interptype); 2292792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 2293792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 2294792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, jac->relaxtype[0]); /* defaults coarse to 9 */ 2295792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps, jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */ 2296792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 2297792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 22986ea7df73SStefano Zampini /* GPU */ 22996ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 2300792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 2301792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRAP2, jac->hsolver, jac->rap2); 2302792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetModuleRAP2, jac->hsolver, jac->mod_rap2); 23036ea7df73SStefano Zampini #endif 23046ea7df73SStefano Zampini 2305589dcaf0SStefano Zampini /* AIR */ 23066ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 2307792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 2308792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 2309792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 2310792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 2311792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 23126ea7df73SStefano Zampini #endif 23133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 231416d9e3a6SLisandro Dalcin } 23159566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ams", jac->hypre_type, &flag)); 23164cb006feSStefano Zampini if (flag) { 23173ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_AMSCreate, &jac->hsolver); 23184cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 23194cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 23204cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 23214cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 23224cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 23234cb006feSStefano Zampini jac->coords[0] = NULL; 23244cb006feSStefano Zampini jac->coords[1] = NULL; 23254cb006feSStefano Zampini jac->coords[2] = NULL; 2326be14dc20SKerry Key jac->interior = NULL; 23274cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 2328863406b8SStefano Zampini jac->as_print = 0; 2329863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2330863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 23314cb006feSStefano Zampini jac->ams_cycle_type = 13; 23324cb006feSStefano Zampini /* Smoothing options */ 2333863406b8SStefano Zampini jac->as_relax_type = 2; 2334863406b8SStefano Zampini jac->as_relax_times = 1; 2335863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2336863406b8SStefano Zampini jac->as_omega = 1.0; 23374cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2338863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2339863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 23400bdd8552SBarry Smith jac->as_amg_alpha_opts[2] = 6; 2341863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2342863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2343863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 23444cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2345863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2346863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 23470bdd8552SBarry Smith jac->as_amg_beta_opts[2] = 6; 2348863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2349863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2350863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2351792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 2352792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 2353792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2354792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 23559371c9d4SSatish Balay PetscCallExternal(HYPRE_AMSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2356792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2357863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2358863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 23599371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2360a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2361792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2362863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2363863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 23649371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2365a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 236623df4f25SStefano Zampini /* Zero conductivity */ 236723df4f25SStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 236823df4f25SStefano Zampini jac->ams_beta_is_zero_part = PETSC_FALSE; 23693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23704cb006feSStefano Zampini } 23719566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ads", jac->hypre_type, &flag)); 2372863406b8SStefano Zampini if (flag) { 23733ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_ADSCreate, &jac->hsolver); 2374863406b8SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ADS; 2375863406b8SStefano Zampini pc->ops->view = PCView_HYPRE_ADS; 2376863406b8SStefano Zampini jac->destroy = HYPRE_ADSDestroy; 2377863406b8SStefano Zampini jac->setup = HYPRE_ADSSetup; 2378863406b8SStefano Zampini jac->solve = HYPRE_ADSSolve; 2379863406b8SStefano Zampini jac->coords[0] = NULL; 2380863406b8SStefano Zampini jac->coords[1] = NULL; 2381863406b8SStefano Zampini jac->coords[2] = NULL; 2382863406b8SStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */ 2383863406b8SStefano Zampini jac->as_print = 0; 2384863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2385863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 2386863406b8SStefano Zampini jac->ads_cycle_type = 13; 2387863406b8SStefano Zampini /* Smoothing options */ 2388863406b8SStefano Zampini jac->as_relax_type = 2; 2389863406b8SStefano Zampini jac->as_relax_times = 1; 2390863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2391863406b8SStefano Zampini jac->as_omega = 1.0; 2392863406b8SStefano Zampini /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2393863406b8SStefano Zampini jac->ams_cycle_type = 14; 2394863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2395863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 2396863406b8SStefano Zampini jac->as_amg_alpha_opts[2] = 6; 2397863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2398863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2399863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 2400863406b8SStefano Zampini /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2401863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2402863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 2403863406b8SStefano Zampini jac->as_amg_beta_opts[2] = 6; 2404863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2405863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2406863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2407792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 2408792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 2409792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2410792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 24119371c9d4SSatish Balay PetscCallExternal(HYPRE_ADSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2412792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMG coarsen type */ 2413863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2414863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2415863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 24169371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2417a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2418792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2419863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2420863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 24219371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2422a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 24233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2424863406b8SStefano Zampini } 24259566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 24262fa5cd67SKarl Rupp 24270298fd71SBarry Smith jac->hypre_type = NULL; 242898921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams", name); 242916d9e3a6SLisandro Dalcin } 243016d9e3a6SLisandro Dalcin 243116d9e3a6SLisandro Dalcin /* 243216d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 243316d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 243416d9e3a6SLisandro Dalcin */ 2435ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE(PC pc, PetscOptionItems *PetscOptionsObject) 2436d71ae5a4SJacob Faibussowitsch { 24374ddd07fcSJed Brown PetscInt indx; 24383c61a47dSLukas const char *type[] = {"ilu", "euclid", "pilut", "parasails", "boomeramg", "ams", "ads"}; 2439ace3abfcSBarry Smith PetscBool flg; 244016d9e3a6SLisandro Dalcin 244116d9e3a6SLisandro Dalcin PetscFunctionBegin; 2442d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE preconditioner options"); 2443dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_type", "HYPRE preconditioner type", "PCHYPRESetType", type, PETSC_STATIC_ARRAY_LENGTH(type), "boomeramg", &indx, &flg)); 244416d9e3a6SLisandro Dalcin if (flg) { 24459566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc, type[indx])); 244602a17cd4SBarry Smith } else { 24479566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc, "boomeramg")); 244816d9e3a6SLisandro Dalcin } 2449dbbe0bcdSBarry Smith PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject); 2450d0609cedSBarry Smith PetscOptionsHeadEnd(); 24513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 245216d9e3a6SLisandro Dalcin } 245316d9e3a6SLisandro Dalcin 2454cc4c1da9SBarry Smith /*@ 245516d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 245616d9e3a6SLisandro Dalcin 245716d9e3a6SLisandro Dalcin Input Parameters: 245816d9e3a6SLisandro Dalcin + pc - the preconditioner context 2459db966c6cSHong Zhang - name - either euclid, pilut, parasails, boomeramg, ams, ads 246016d9e3a6SLisandro Dalcin 2461f1580f4eSBarry Smith Options Database Key: 2462feefa0e1SJacob Faibussowitsch . pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 246316d9e3a6SLisandro Dalcin 246416d9e3a6SLisandro Dalcin Level: intermediate 246516d9e3a6SLisandro Dalcin 2466562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRE` 246716d9e3a6SLisandro Dalcin @*/ 2468d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetType(PC pc, const char name[]) 2469d71ae5a4SJacob Faibussowitsch { 247016d9e3a6SLisandro Dalcin PetscFunctionBegin; 24710700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 24724f572ea9SToby Isaac PetscAssertPointer(name, 2); 2473cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetType_C", (PC, const char[]), (pc, name)); 24743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 247516d9e3a6SLisandro Dalcin } 247616d9e3a6SLisandro Dalcin 2477cc4c1da9SBarry Smith /*@ 247816d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 247916d9e3a6SLisandro Dalcin 248016d9e3a6SLisandro Dalcin Input Parameter: 248116d9e3a6SLisandro Dalcin . pc - the preconditioner context 248216d9e3a6SLisandro Dalcin 248316d9e3a6SLisandro Dalcin Output Parameter: 2484db966c6cSHong Zhang . name - either euclid, pilut, parasails, boomeramg, ams, ads 248516d9e3a6SLisandro Dalcin 248616d9e3a6SLisandro Dalcin Level: intermediate 248716d9e3a6SLisandro Dalcin 2488562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`, `PCHYPRE` 248916d9e3a6SLisandro Dalcin @*/ 2490d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREGetType(PC pc, const char *name[]) 2491d71ae5a4SJacob Faibussowitsch { 249216d9e3a6SLisandro Dalcin PetscFunctionBegin; 24930700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 24944f572ea9SToby Isaac PetscAssertPointer(name, 2); 2495cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPREGetType_C", (PC, const char *[]), (pc, name)); 24963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 249716d9e3a6SLisandro Dalcin } 249816d9e3a6SLisandro Dalcin 2499cc4c1da9SBarry Smith /*@ 2500f1580f4eSBarry Smith PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use on GPUs 2501db6f9c32SMark Adams 2502c3339decSBarry Smith Logically Collective 2503db6f9c32SMark Adams 2504db6f9c32SMark Adams Input Parameters: 2505db6f9c32SMark Adams + pc - the hypre context 2506feefa0e1SJacob Faibussowitsch - name - one of 'cusparse', 'hypre' 2507db6f9c32SMark Adams 2508db6f9c32SMark Adams Options Database Key: 250967b8a455SSatish Balay . -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre 2510db6f9c32SMark Adams 2511db6f9c32SMark Adams Level: intermediate 2512db6f9c32SMark Adams 2513feefa0e1SJacob Faibussowitsch Developer Notes: 2514f1580f4eSBarry Smith How the name starts with `PCMG`, should it not be `PCHYPREBoomerAMG`? 2515db6f9c32SMark Adams 2516562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinGetMatProductAlgorithm()` 2517db6f9c32SMark Adams @*/ 2518d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc, const char name[]) 2519d71ae5a4SJacob Faibussowitsch { 2520db6f9c32SMark Adams PetscFunctionBegin; 2521db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2522cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinSetMatProductAlgorithm_C", (PC, const char[]), (pc, name)); 25233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2524db6f9c32SMark Adams } 2525db6f9c32SMark Adams 2526cc4c1da9SBarry Smith /*@ 2527f1580f4eSBarry Smith PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre to use on GPUs 2528db6f9c32SMark Adams 2529db6f9c32SMark Adams Not Collective 2530db6f9c32SMark Adams 2531db6f9c32SMark Adams Input Parameter: 2532db6f9c32SMark Adams . pc - the multigrid context 2533db6f9c32SMark Adams 2534db6f9c32SMark Adams Output Parameter: 2535db6f9c32SMark Adams . name - one of 'cusparse', 'hypre' 2536db6f9c32SMark Adams 2537db6f9c32SMark Adams Level: intermediate 2538db6f9c32SMark Adams 2539a94f484eSPierre Jolivet .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinSetMatProductAlgorithm()` 2540db6f9c32SMark Adams @*/ 2541d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc, const char *name[]) 2542d71ae5a4SJacob Faibussowitsch { 2543db6f9c32SMark Adams PetscFunctionBegin; 2544db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2545cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinGetMatProductAlgorithm_C", (PC, const char *[]), (pc, name)); 25463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2547db6f9c32SMark Adams } 2548db6f9c32SMark Adams 254916d9e3a6SLisandro Dalcin /*MC 2550f1580f4eSBarry Smith PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre as PETSc `PC` 255116d9e3a6SLisandro Dalcin 255216d9e3a6SLisandro Dalcin Options Database Keys: 2553e1ded407SBarry Smith + -pc_hypre_type - One of `euclid`, `pilut`, `parasails`, `boomeramg`, `ams`, or `ads` 2554*7cbeddf0SNuno Nobre . -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see `HYPRE_BoomerAMGSetNodal()`) 2555f1580f4eSBarry Smith . -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see `HYPRE_BoomerAMGSetInterpVecVariant()`) 2556*7cbeddf0SNuno Nobre - Many others - run with `-pc_type hypre` `-pc_hypre_type XXX` `-help` to see options for the XXX preconditioner 255716d9e3a6SLisandro Dalcin 255816d9e3a6SLisandro Dalcin Level: intermediate 255916d9e3a6SLisandro Dalcin 256095452b02SPatrick Sanan Notes: 2561e1ded407SBarry Smith Apart from `-pc_hypre_type` (for which there is `PCHYPRESetType()`), 256216d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 256349567fc5SPierre Jolivet or with `PetscOptionsSetValue()`, there are no functions to set them) 256416d9e3a6SLisandro Dalcin 2565e1ded407SBarry Smith The options `-pc_hypre_boomeramg_max_iter` and `-pc_hypre_boomeramg_tol` refer to the number of iterations 2566e1ded407SBarry Smith (V-cycles) and tolerance that boomerAMG does EACH time it is called. So for example, if 2567e1ded407SBarry Smith `-pc_hypre_boomeramg_max_iter` is set to 2 then 2-V-cycles are being used to define the preconditioner 2568e1ded407SBarry Smith (`-pc_hypre_boomeramg_tol` should be set to 0.0 - the default - to strictly use a fixed number of 2569e1ded407SBarry Smith iterations per hypre call). `-ksp_max_it` and `-ksp_rtol` STILL determine the total number of iterations 2570e1ded407SBarry Smith and tolerance for the Krylov solver. For example, if `-pc_hypre_boomeramg_max_iter` is 2 and `-ksp_max_it` is 10 2571e1ded407SBarry Smith then AT MOST twenty V-cycles of boomeramg will be used. 257216d9e3a6SLisandro Dalcin 2573e1ded407SBarry Smith Note that the option `-pc_hypre_boomeramg_relax_type_all` defaults to symmetric relaxation 25740f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 2575e1ded407SBarry Smith Otherwise, you may want to use `-pc_hypre_boomeramg_relax_type_all SOR/Jacobi`. 257616d9e3a6SLisandro Dalcin 2577f1580f4eSBarry Smith `MatSetNearNullSpace()` - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use 2578e1ded407SBarry Smith the following two options: `-pc_hypre_boomeramg_nodal_coarsen <n> -pc_hypre_boomeramg_vec_interp_variant <v>` 25790b1a5bd9SEric Chamberland 2580f1580f4eSBarry Smith See `PCPFMG`, `PCSMG`, and `PCSYSPFMG` for access to hypre's other (nonalgebraic) multigrid solvers 2581f1580f4eSBarry Smith 2582e1ded407SBarry Smith For `PCHYPRE` type of `ams` or `ads` auxiliary data must be provided to the preconditioner with `PCHYPRESetDiscreteGradient()`, 2583f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 258449567fc5SPierre Jolivet `PCHYPREAMSSetInteriorNodes()` 2585f1580f4eSBarry Smith 2586e1ded407SBarry 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 2587e1ded407SBarry Smith since it is usually slower, one should use a `KSPType` of `KSPRICHARDSON` 2588e1ded407SBarry Smith (or equivalently `-ksp_type richardson`) to achieve this. Using `KSPPREONLY` will not work since it only applies a single cycle of multigrid. 2589e1ded407SBarry Smith 2590f1580f4eSBarry Smith PETSc provides its own geometric and algebraic multigrid solvers `PCMG` and `PCGAMG`, also see `PCHMG` which is useful for certain multicomponent problems 25919e5bc791SBarry Smith 2592ead8c081SBarry Smith GPU Notes: 2593ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda 2594f1580f4eSBarry Smith Then pass `VECCUDA` vectors and `MATAIJCUSPARSE` matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2595ead8c081SBarry Smith 2596ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip 2597f1580f4eSBarry Smith Then pass `VECHIP` vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2598ead8c081SBarry Smith 2599562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRESetType()`, `PCPFMG`, `PCGAMG`, `PCSYSPFMG`, `PCSMG`, `PCHYPRESetDiscreteGradient()`, 2600f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 2601f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes() 260216d9e3a6SLisandro Dalcin M*/ 260316d9e3a6SLisandro Dalcin 2604d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 2605d71ae5a4SJacob Faibussowitsch { 260616d9e3a6SLisandro Dalcin PC_HYPRE *jac; 260716d9e3a6SLisandro Dalcin 260816d9e3a6SLisandro Dalcin PetscFunctionBegin; 26094dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac)); 26102fa5cd67SKarl Rupp 261116d9e3a6SLisandro Dalcin pc->data = jac; 26128695de01SBarry Smith pc->ops->reset = PCReset_HYPRE; 261316d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 261416d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 261516d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 261616d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 261716d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 26189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", PCHYPRESetType_HYPRE)); 26199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", PCHYPREGetType_HYPRE)); 26209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", PCSetCoordinates_HYPRE)); 26219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", PCHYPRESetDiscreteGradient_HYPRE)); 26229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", PCHYPRESetDiscreteCurl_HYPRE)); 26239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", PCHYPRESetInterpolations_HYPRE)); 26249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", PCHYPRESetEdgeConstantVectors_HYPRE)); 2625be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", PCHYPREAMSSetInteriorNodes_HYPRE)); 26269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", PCHYPRESetPoissonMatrix_HYPRE)); 26279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG)); 26289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG)); 26296ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 26306ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 26319566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 26326ea7df73SStefano Zampini #endif 26336ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 26349566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 26356ea7df73SStefano Zampini #endif 26366ea7df73SStefano Zampini #endif 2637ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 26383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 263916d9e3a6SLisandro Dalcin } 2640ebc551c0SBarry Smith 2641ebc551c0SBarry Smith typedef struct { 264268326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 2643f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 26449e5bc791SBarry Smith 26459e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 26464ddd07fcSJed Brown PetscInt its; 264773dcfd97SStefano Zampini PetscReal tol; 26484ddd07fcSJed Brown PetscInt relax_type; 26494ddd07fcSJed Brown PetscInt rap_type; 26504ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 26514ddd07fcSJed Brown PetscInt max_levels; 26520be8cd64Sftrigaux PetscInt skip_relax; 26530be8cd64Sftrigaux PetscBool print_statistics; 2654ebc551c0SBarry Smith } PC_PFMG; 2655ebc551c0SBarry Smith 2656ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_PFMG(PC pc) 2657d71ae5a4SJacob Faibussowitsch { 2658f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2659ebc551c0SBarry Smith 2660ebc551c0SBarry Smith PetscFunctionBegin; 2661792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 26629566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 26639566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 26643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2665ebc551c0SBarry Smith } 2666ebc551c0SBarry Smith 26679e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi", "Weighted-Jacobi", "symmetric-Red/Black-Gauss-Seidel", "Red/Black-Gauss-Seidel"}; 26689e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin", "non-Galerkin"}; 26699e5bc791SBarry Smith 2670ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_PFMG(PC pc, PetscViewer viewer) 2671d71ae5a4SJacob Faibussowitsch { 2672ace3abfcSBarry Smith PetscBool iascii; 2673f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2674ebc551c0SBarry Smith 2675ebc551c0SBarry Smith PetscFunctionBegin; 26769566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 26779e5bc791SBarry Smith if (iascii) { 26789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE PFMG preconditioning\n")); 267963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 26809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 26819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 26829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " RAP type %s\n", PFMGRAPType[ex->rap_type])); 268363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 268463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max levels %" PetscInt_FMT "\n", ex->max_levels)); 26850be8cd64Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " skip relax %" PetscInt_FMT "\n", ex->skip_relax)); 26869e5bc791SBarry Smith } 26873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2688ebc551c0SBarry Smith } 2689ebc551c0SBarry Smith 2690ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_PFMG(PC pc, PetscOptionItems *PetscOptionsObject) 2691d71ae5a4SJacob Faibussowitsch { 2692f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2693ebc551c0SBarry Smith 2694ebc551c0SBarry Smith PetscFunctionBegin; 2695d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PFMG options"); 26960be8cd64Sftrigaux PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics", "Print statistics", "HYPRE_StructPFMGSetPrintLevel", ex->print_statistics, &ex->print_statistics, NULL)); 26979566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_its", "Number of iterations of PFMG to use as preconditioner", "HYPRE_StructPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2698792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 26999566063dSJacob 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)); 2700792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 27019566063dSJacob 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)); 2702792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 27039e5bc791SBarry Smith 27049566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_max_levels", "Max Levels for MG hierarchy", "HYPRE_StructPFMGSetMaxLevels", ex->max_levels, &ex->max_levels, NULL)); 2705792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 27063b46a515SGlenn Hammond 27079566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_pfmg_tol", "Tolerance of PFMG", "HYPRE_StructPFMGSetTol", ex->tol, &ex->tol, NULL)); 2708792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 2709dd39110bSPierre 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)); 2710792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 2711dd39110bSPierre 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)); 2712792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 27130be8cd64Sftrigaux 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)); 27140be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetSkipRelax, ex->hsolver, ex->skip_relax); 2715d0609cedSBarry Smith PetscOptionsHeadEnd(); 27163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2717ebc551c0SBarry Smith } 2718ebc551c0SBarry Smith 2719ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_PFMG(PC pc, Vec x, Vec y) 2720d71ae5a4SJacob Faibussowitsch { 2721f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2722d9ca1df4SBarry Smith PetscScalar *yy; 2723d9ca1df4SBarry Smith const PetscScalar *xx; 27244ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 27252cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 2726f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 2727f91d8e95SBarry Smith 2728f91d8e95SBarry Smith PetscFunctionBegin; 27299566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 27309566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 27312cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2732f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 2733f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 2734f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 27352cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 27362cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 27372cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 27382cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 27392cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 27402cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2741f91d8e95SBarry Smith 2742f91d8e95SBarry Smith /* copy x values over to hypre */ 2743792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 27449566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2745792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 27469566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2747792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 2748792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2749f91d8e95SBarry Smith 2750f91d8e95SBarry Smith /* copy solution values back to PETSc */ 27519566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2752792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 27539566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 27543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2755f91d8e95SBarry Smith } 2756f91d8e95SBarry Smith 2757d71ae5a4SJacob 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) 2758d71ae5a4SJacob Faibussowitsch { 27599e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG *)pc->data; 27602cf14000SStefano Zampini HYPRE_Int oits; 27619e5bc791SBarry Smith 27629e5bc791SBarry Smith PetscFunctionBegin; 27639566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 2764792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, its * jac->its); 2765792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, rtol); 27669e5bc791SBarry Smith 27679566063dSJacob Faibussowitsch PetscCall(PCApply_PFMG(pc, b, y)); 2768792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGGetNumIterations, jac->hsolver, &oits); 27699e5bc791SBarry Smith *outits = oits; 27709e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 27719e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 2772792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, jac->tol); 2773792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, jac->its); 27743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27759e5bc791SBarry Smith } 27769e5bc791SBarry Smith 2777ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_PFMG(PC pc) 2778d71ae5a4SJacob Faibussowitsch { 27793a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG *)pc->data; 2780f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 2781ace3abfcSBarry Smith PetscBool flg; 27823a32d3dbSGlenn Hammond 27833a32d3dbSGlenn Hammond PetscFunctionBegin; 27849566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 278528b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 27863a32d3dbSGlenn Hammond 27873a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 2788792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 2789792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 27900be8cd64Sftrigaux 27910be8cd64Sftrigaux // Print Hypre statistics about the solve process 27920be8cd64Sftrigaux if (ex->print_statistics) PetscCallExternal(HYPRE_StructPFMGSetPrintLevel, ex->hsolver, 3); 27930be8cd64Sftrigaux 27940be8cd64Sftrigaux // The hypre options must be repeated here because the StructPFMG was destroyed and recreated 27950be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 27960be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 27970be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 27980be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 27990be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 28000be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 28010be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 28020be8cd64Sftrigaux 2803792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2804792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetZeroGuess, ex->hsolver); 28053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28063a32d3dbSGlenn Hammond } 28073a32d3dbSGlenn Hammond 2808ebc551c0SBarry Smith /*MC 2809ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 2810ebc551c0SBarry Smith 2811f1580f4eSBarry Smith Options Database Keys: 281267b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner 281367b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve 281467b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve 281567b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG 28169e5bc791SBarry 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 28170be8cd64Sftrigaux . -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 2818f1580f4eSBarry Smith - -pc_pfmg_skip_relax - skip relaxation on certain grids for isotropic problems. This can greatly improve efficiency by eliminating unnecessary relaxations 2819f1580f4eSBarry Smith when the underlying problem is isotropic, one of 0,1 2820f1580f4eSBarry Smith 2821f1580f4eSBarry Smith Level: advanced 2822f91d8e95SBarry Smith 282395452b02SPatrick Sanan Notes: 282495452b02SPatrick Sanan This is for CELL-centered descretizations 28259e5bc791SBarry Smith 2826f1580f4eSBarry Smith See `PCSYSPFMG` for a version suitable for systems of PDEs, and `PCSMG` 28279e5bc791SBarry Smith 2828f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 2829f1580f4eSBarry Smith 2830f1580f4eSBarry Smith This must be used with the `MATHYPRESTRUCT` matrix type. 2831f1580f4eSBarry Smith 2832f1580f4eSBarry Smith This provides only some of the functionality of PFMG, it supports only one block per process defined by a PETSc `DMDA`. 2833f1580f4eSBarry Smith 2834562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESTRUCT`, `PCHYPRE`, `PCGAMG`, `PCSYSPFMG`, `PCSMG` 2835ebc551c0SBarry Smith M*/ 2836ebc551c0SBarry Smith 2837d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 2838d71ae5a4SJacob Faibussowitsch { 2839ebc551c0SBarry Smith PC_PFMG *ex; 2840ebc551c0SBarry Smith 2841ebc551c0SBarry Smith PetscFunctionBegin; 28429371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 284368326731SBarry Smith pc->data = ex; 2844ebc551c0SBarry Smith 28459e5bc791SBarry Smith ex->its = 1; 28469e5bc791SBarry Smith ex->tol = 1.e-8; 28479e5bc791SBarry Smith ex->relax_type = 1; 28489e5bc791SBarry Smith ex->rap_type = 0; 28499e5bc791SBarry Smith ex->num_pre_relax = 1; 28509e5bc791SBarry Smith ex->num_post_relax = 1; 28513b46a515SGlenn Hammond ex->max_levels = 0; 28520be8cd64Sftrigaux ex->skip_relax = 0; 28530be8cd64Sftrigaux ex->print_statistics = PETSC_FALSE; 28549e5bc791SBarry Smith 2855ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 2856ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 2857ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 2858f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 28599e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 286068326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 28612fa5cd67SKarl Rupp 28629566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 2863ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 2864792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 28653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2866ebc551c0SBarry Smith } 2867d851a50bSGlenn Hammond 2868d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 2869d851a50bSGlenn Hammond typedef struct { 2870d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 2871d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 2872d851a50bSGlenn Hammond 2873d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 28744ddd07fcSJed Brown PetscInt its; 287573dcfd97SStefano Zampini PetscReal tol; 28764ddd07fcSJed Brown PetscInt relax_type; 28774ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 2878d851a50bSGlenn Hammond } PC_SysPFMG; 2879d851a50bSGlenn Hammond 2880ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SysPFMG(PC pc) 2881d71ae5a4SJacob Faibussowitsch { 2882d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2883d851a50bSGlenn Hammond 2884d851a50bSGlenn Hammond PetscFunctionBegin; 2885792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 28869566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 28879566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 28883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2889d851a50bSGlenn Hammond } 2890d851a50bSGlenn Hammond 2891d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi", "Red/Black-Gauss-Seidel"}; 2892d851a50bSGlenn Hammond 2893ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SysPFMG(PC pc, PetscViewer viewer) 2894d71ae5a4SJacob Faibussowitsch { 2895ace3abfcSBarry Smith PetscBool iascii; 2896d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2897d851a50bSGlenn Hammond 2898d851a50bSGlenn Hammond PetscFunctionBegin; 28999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 2900d851a50bSGlenn Hammond if (iascii) { 29019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SysPFMG preconditioning\n")); 290263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 29039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 29049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 290563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 2906d851a50bSGlenn Hammond } 29073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2908d851a50bSGlenn Hammond } 2909d851a50bSGlenn Hammond 2910ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_SysPFMG(PC pc, PetscOptionItems *PetscOptionsObject) 2911d71ae5a4SJacob Faibussowitsch { 2912d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2913ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2914d851a50bSGlenn Hammond 2915d851a50bSGlenn Hammond PetscFunctionBegin; 2916d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SysPFMG options"); 29179566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics", "Print statistics", "HYPRE_SStructSysPFMGSetPrintLevel", flg, &flg, NULL)); 291848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_SStructSysPFMGSetPrintLevel, ex->ss_solver, 3); 29199566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_its", "Number of iterations of SysPFMG to use as preconditioner", "HYPRE_SStructSysPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2920792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, ex->ss_solver, ex->its); 29219566063dSJacob 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)); 2922792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPreRelax, ex->ss_solver, ex->num_pre_relax); 29239566063dSJacob 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)); 2924792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPostRelax, ex->ss_solver, ex->num_post_relax); 2925d851a50bSGlenn Hammond 29269566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_syspfmg_tol", "Tolerance of SysPFMG", "HYPRE_SStructSysPFMGSetTol", ex->tol, &ex->tol, NULL)); 2927792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, ex->ss_solver, ex->tol); 2928dd39110bSPierre 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)); 2929792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetRelaxType, ex->ss_solver, ex->relax_type); 2930d0609cedSBarry Smith PetscOptionsHeadEnd(); 29313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2932d851a50bSGlenn Hammond } 2933d851a50bSGlenn Hammond 2934ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SysPFMG(PC pc, Vec x, Vec y) 2935d71ae5a4SJacob Faibussowitsch { 2936d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2937d9ca1df4SBarry Smith PetscScalar *yy; 2938d9ca1df4SBarry Smith const PetscScalar *xx; 29394ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 29402cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 2941f4f49eeaSPierre Jolivet Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)pc->pmat->data; 29424ddd07fcSJed Brown PetscInt ordering = mx->dofs_order; 29434ddd07fcSJed Brown PetscInt nvars = mx->nvars; 29444ddd07fcSJed Brown PetscInt part = 0; 29454ddd07fcSJed Brown PetscInt size; 29464ddd07fcSJed Brown PetscInt i; 2947d851a50bSGlenn Hammond 2948d851a50bSGlenn Hammond PetscFunctionBegin; 29499566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 29509566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 29512cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2952d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 2953d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 2954d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 29552cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 29562cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 29572cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 29582cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 29592cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 29602cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2961d851a50bSGlenn Hammond 2962d851a50bSGlenn Hammond size = 1; 29632fa5cd67SKarl Rupp for (i = 0; i < 3; i++) size *= (iupper[i] - ilower[i] + 1); 29642fa5cd67SKarl Rupp 2965d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 2966d851a50bSGlenn Hammond if (ordering) { 2967792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 29689566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2969792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(xx + (size * i))); 29709566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2971792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 2972792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructMatrixMatvec, 1.0, mx->ss_mat, mx->ss_b, 0.0, mx->ss_x); 2973792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 2974d851a50bSGlenn Hammond 2975d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 29769566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2977792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(yy + (size * i))); 29789566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 2979a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 2980d851a50bSGlenn Hammond PetscScalar *z; 29814ddd07fcSJed Brown PetscInt j, k; 2982d851a50bSGlenn Hammond 29839566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvars * size, &z)); 2984792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 29859566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2986d851a50bSGlenn Hammond 2987d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 2988d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 2989d851a50bSGlenn Hammond k = i * nvars; 29902fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) z[j * size + i] = xx[k + j]; 2991d851a50bSGlenn Hammond } 2992792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 29939566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2994792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 2995792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 2996d851a50bSGlenn Hammond 2997d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 29989566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2999792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 3000d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 3001d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 3002d851a50bSGlenn Hammond k = i * nvars; 30032fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) yy[k + j] = z[j * size + i]; 3004d851a50bSGlenn Hammond } 30059566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 30069566063dSJacob Faibussowitsch PetscCall(PetscFree(z)); 3007d851a50bSGlenn Hammond } 30083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3009d851a50bSGlenn Hammond } 3010d851a50bSGlenn Hammond 3011d71ae5a4SJacob 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) 3012d71ae5a4SJacob Faibussowitsch { 3013d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG *)pc->data; 30142cf14000SStefano Zampini HYPRE_Int oits; 3015d851a50bSGlenn Hammond 3016d851a50bSGlenn Hammond PetscFunctionBegin; 30179566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 3018792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, its * jac->its); 3019792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, rtol); 30209566063dSJacob Faibussowitsch PetscCall(PCApply_SysPFMG(pc, b, y)); 3021792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGGetNumIterations, jac->ss_solver, &oits); 3022d851a50bSGlenn Hammond *outits = oits; 3023d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 3024d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 3025792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, jac->tol); 3026792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, jac->its); 30273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3028d851a50bSGlenn Hammond } 3029d851a50bSGlenn Hammond 3030ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SysPFMG(PC pc) 3031d71ae5a4SJacob Faibussowitsch { 3032d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 3033f4f49eeaSPierre Jolivet Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)pc->pmat->data; 3034ace3abfcSBarry Smith PetscBool flg; 3035d851a50bSGlenn Hammond 3036d851a50bSGlenn Hammond PetscFunctionBegin; 30379566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESSTRUCT, &flg)); 303828b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESSTRUCT with this preconditioner"); 3039d851a50bSGlenn Hammond 3040d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 3041792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 3042792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 3043792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetZeroGuess, ex->ss_solver); 3044792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetup, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 30453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3046d851a50bSGlenn Hammond } 3047d851a50bSGlenn Hammond 3048d851a50bSGlenn Hammond /*MC 3049f1580f4eSBarry Smith PCSYSPFMG - the hypre SysPFMG multigrid solver 3050d851a50bSGlenn Hammond 3051d851a50bSGlenn Hammond Level: advanced 3052d851a50bSGlenn Hammond 3053f1580f4eSBarry Smith Options Database Keys: 305467b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner 305567b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid 305667b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid 305767b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG 305867b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles 3059d851a50bSGlenn Hammond 306095452b02SPatrick Sanan Notes: 3061f1580f4eSBarry Smith See `PCPFMG` for hypre's PFMG that works for a scalar PDE and `PCSMG` 3062f1580f4eSBarry Smith 3063f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 3064f1580f4eSBarry Smith 306595452b02SPatrick Sanan This is for CELL-centered descretizations 3066d851a50bSGlenn Hammond 3067f1580f4eSBarry Smith This must be used with the `MATHYPRESSTRUCT` matrix type. 3068d851a50bSGlenn Hammond 3069f1580f4eSBarry 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`. 3070f1580f4eSBarry Smith 3071562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESSTRUCT`, `PCPFMG`, `PCHYPRE`, `PCGAMG`, `PCSMG` 3072d851a50bSGlenn Hammond M*/ 3073d851a50bSGlenn Hammond 3074d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 3075d71ae5a4SJacob Faibussowitsch { 3076d851a50bSGlenn Hammond PC_SysPFMG *ex; 3077d851a50bSGlenn Hammond 3078d851a50bSGlenn Hammond PetscFunctionBegin; 30799371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 3080d851a50bSGlenn Hammond pc->data = ex; 3081d851a50bSGlenn Hammond 3082d851a50bSGlenn Hammond ex->its = 1; 3083d851a50bSGlenn Hammond ex->tol = 1.e-8; 3084d851a50bSGlenn Hammond ex->relax_type = 1; 3085d851a50bSGlenn Hammond ex->num_pre_relax = 1; 3086d851a50bSGlenn Hammond ex->num_post_relax = 1; 3087d851a50bSGlenn Hammond 3088d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 3089d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 3090d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 3091d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 3092d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 3093d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 30942fa5cd67SKarl Rupp 30959566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 3096ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 3097792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 30983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3099d851a50bSGlenn Hammond } 31001c188c59Sftrigaux 3101f1580f4eSBarry Smith /* PC SMG */ 31021c188c59Sftrigaux typedef struct { 31031c188c59Sftrigaux MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 31041c188c59Sftrigaux HYPRE_StructSolver hsolver; 31051c188c59Sftrigaux PetscInt its; /* keep copy of SMG options used so may view them */ 310673dcfd97SStefano Zampini PetscReal tol; 31071c188c59Sftrigaux PetscBool print_statistics; 31081c188c59Sftrigaux PetscInt num_pre_relax, num_post_relax; 31091c188c59Sftrigaux } PC_SMG; 31101c188c59Sftrigaux 3111ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SMG(PC pc) 3112d71ae5a4SJacob Faibussowitsch { 31131c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 31141c188c59Sftrigaux 31151c188c59Sftrigaux PetscFunctionBegin; 31161c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, ex->hsolver); 31171c188c59Sftrigaux PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 31181c188c59Sftrigaux PetscCall(PetscFree(pc->data)); 31193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31201c188c59Sftrigaux } 31211c188c59Sftrigaux 3122ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SMG(PC pc, PetscViewer viewer) 3123d71ae5a4SJacob Faibussowitsch { 31241c188c59Sftrigaux PetscBool iascii; 31251c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 31261c188c59Sftrigaux 31271c188c59Sftrigaux PetscFunctionBegin; 31281c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 31291c188c59Sftrigaux if (iascii) { 31301c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SMG preconditioning\n")); 31311c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 31321c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 31331c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 31341c188c59Sftrigaux } 31353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31361c188c59Sftrigaux } 31371c188c59Sftrigaux 3138ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_SMG(PC pc, PetscOptionItems *PetscOptionsObject) 3139d71ae5a4SJacob Faibussowitsch { 31401c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 31411c188c59Sftrigaux 31421c188c59Sftrigaux PetscFunctionBegin; 31431c188c59Sftrigaux PetscOptionsHeadBegin(PetscOptionsObject, "SMG options"); 31441c188c59Sftrigaux 31451c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_its", "Number of iterations of SMG to use as preconditioner", "HYPRE_StructSMGSetMaxIter", ex->its, &ex->its, NULL)); 31461c188c59Sftrigaux 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)); 31471c188c59Sftrigaux 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)); 31481c188c59Sftrigaux PetscCall(PetscOptionsReal("-pc_smg_tol", "Tolerance of SMG", "HYPRE_StructSMGSetTol", ex->tol, &ex->tol, NULL)); 31491c188c59Sftrigaux 31501c188c59Sftrigaux PetscOptionsHeadEnd(); 31513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31521c188c59Sftrigaux } 31531c188c59Sftrigaux 3154ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SMG(PC pc, Vec x, Vec y) 3155d71ae5a4SJacob Faibussowitsch { 31561c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 31571c188c59Sftrigaux PetscScalar *yy; 31581c188c59Sftrigaux const PetscScalar *xx; 31591c188c59Sftrigaux PetscInt ilower[3], iupper[3]; 31601c188c59Sftrigaux HYPRE_Int hlower[3], hupper[3]; 3161f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 31621c188c59Sftrigaux 31631c188c59Sftrigaux PetscFunctionBegin; 31641c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 31651c188c59Sftrigaux PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 31661c188c59Sftrigaux /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 31671c188c59Sftrigaux iupper[0] += ilower[0] - 1; 31681c188c59Sftrigaux iupper[1] += ilower[1] - 1; 31691c188c59Sftrigaux iupper[2] += ilower[2] - 1; 31701c188c59Sftrigaux hlower[0] = (HYPRE_Int)ilower[0]; 31711c188c59Sftrigaux hlower[1] = (HYPRE_Int)ilower[1]; 31721c188c59Sftrigaux hlower[2] = (HYPRE_Int)ilower[2]; 31731c188c59Sftrigaux hupper[0] = (HYPRE_Int)iupper[0]; 31741c188c59Sftrigaux hupper[1] = (HYPRE_Int)iupper[1]; 31751c188c59Sftrigaux hupper[2] = (HYPRE_Int)iupper[2]; 31761c188c59Sftrigaux 31771c188c59Sftrigaux /* copy x values over to hypre */ 31781c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 31791c188c59Sftrigaux PetscCall(VecGetArrayRead(x, &xx)); 31801c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 31811c188c59Sftrigaux PetscCall(VecRestoreArrayRead(x, &xx)); 31821c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 31831c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 31841c188c59Sftrigaux 31851c188c59Sftrigaux /* copy solution values back to PETSc */ 31861c188c59Sftrigaux PetscCall(VecGetArray(y, &yy)); 31871c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 31881c188c59Sftrigaux PetscCall(VecRestoreArray(y, &yy)); 31893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31901c188c59Sftrigaux } 31911c188c59Sftrigaux 3192d71ae5a4SJacob 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) 3193d71ae5a4SJacob Faibussowitsch { 31941c188c59Sftrigaux PC_SMG *jac = (PC_SMG *)pc->data; 31951c188c59Sftrigaux HYPRE_Int oits; 31961c188c59Sftrigaux 31971c188c59Sftrigaux PetscFunctionBegin; 31981c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 31991c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, its * jac->its); 32001c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, rtol); 32011c188c59Sftrigaux 32021c188c59Sftrigaux PetscCall(PCApply_SMG(pc, b, y)); 32031c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGGetNumIterations, jac->hsolver, &oits); 32041c188c59Sftrigaux *outits = oits; 32051c188c59Sftrigaux if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 32061c188c59Sftrigaux else *reason = PCRICHARDSON_CONVERGED_RTOL; 32071c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, jac->tol); 32081c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, jac->its); 32093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32101c188c59Sftrigaux } 32111c188c59Sftrigaux 3212ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SMG(PC pc) 3213d71ae5a4SJacob Faibussowitsch { 32141c188c59Sftrigaux PetscInt i, dim; 32151c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 3216f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 32171c188c59Sftrigaux PetscBool flg; 32181c188c59Sftrigaux DMBoundaryType p[3]; 32191c188c59Sftrigaux PetscInt M[3]; 32201c188c59Sftrigaux 32211c188c59Sftrigaux PetscFunctionBegin; 32221c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 32231c188c59Sftrigaux PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 32241c188c59Sftrigaux 32251c188c59Sftrigaux PetscCall(DMDAGetInfo(mx->da, &dim, &M[0], &M[1], &M[2], 0, 0, 0, 0, 0, &p[0], &p[1], &p[2], 0)); 32261c188c59Sftrigaux // Check if power of 2 in periodic directions 32271c188c59Sftrigaux for (i = 0; i < dim; i++) { 32281c188c59Sftrigaux if (((M[i] & (M[i] - 1)) != 0) && (p[i] == DM_BOUNDARY_PERIODIC)) { 32291c188c59Sftrigaux 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]); 32301c188c59Sftrigaux } 32311c188c59Sftrigaux } 32321c188c59Sftrigaux 32331c188c59Sftrigaux /* create the hypre solver object and set its information */ 323457508eceSPierre Jolivet if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, ex->hsolver); 32351c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 32361c188c59Sftrigaux // The hypre options must be set here and not in SetFromOptions because it is created here! 32371c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, ex->hsolver, ex->its); 32381c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 32391c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 32401c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, ex->hsolver, ex->tol); 32411c188c59Sftrigaux 32421c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 32431c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetZeroGuess, ex->hsolver); 32443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32451c188c59Sftrigaux } 32461c188c59Sftrigaux 32471c188c59Sftrigaux /*MC 32485cb80ecdSBarry Smith PCSMG - the hypre (structured grid) SMG multigrid solver 32491c188c59Sftrigaux 32501c188c59Sftrigaux Level: advanced 32511c188c59Sftrigaux 3252f1580f4eSBarry Smith Options Database Keys: 32535cb80ecdSBarry Smith + -pc_smg_its <its> - number of iterations of SMG to use as preconditioner 32545cb80ecdSBarry Smith . -pc_smg_num_pre_relax <steps> - number of smoothing steps before coarse grid 32555cb80ecdSBarry Smith . -pc_smg_num_post_relax <steps> - number of smoothing steps after coarse grid 32565cb80ecdSBarry Smith - -pc_smg_tol <tol> - tolerance of SMG 32571c188c59Sftrigaux 32581c188c59Sftrigaux Notes: 32591c188c59Sftrigaux This is for CELL-centered descretizations 32601c188c59Sftrigaux 32615cb80ecdSBarry Smith This must be used with the `MATHYPRESTRUCT` `MatType`. 32621c188c59Sftrigaux 3263f1580f4eSBarry 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`. 3264f1580f4eSBarry Smith 3265f1580f4eSBarry Smith See `PCSYSPFMG`, `PCSMG`, `PCPFMG`, and `PCHYPRE` for access to hypre's other preconditioners 3266f1580f4eSBarry Smith 3267f1580f4eSBarry Smith .seealso: `PCMG`, `MATHYPRESTRUCT`, `PCPFMG`, `PCSYSPFMG`, `PCHYPRE`, `PCGAMG` 32681c188c59Sftrigaux M*/ 32691c188c59Sftrigaux 3270d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SMG(PC pc) 3271d71ae5a4SJacob Faibussowitsch { 32721c188c59Sftrigaux PC_SMG *ex; 32731c188c59Sftrigaux 32741c188c59Sftrigaux PetscFunctionBegin; 32759371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 32761c188c59Sftrigaux pc->data = ex; 32771c188c59Sftrigaux 32781c188c59Sftrigaux ex->its = 1; 32791c188c59Sftrigaux ex->tol = 1.e-8; 32801c188c59Sftrigaux ex->num_pre_relax = 1; 32811c188c59Sftrigaux ex->num_post_relax = 1; 32821c188c59Sftrigaux 32831c188c59Sftrigaux pc->ops->setfromoptions = PCSetFromOptions_SMG; 32841c188c59Sftrigaux pc->ops->view = PCView_SMG; 32851c188c59Sftrigaux pc->ops->destroy = PCDestroy_SMG; 32861c188c59Sftrigaux pc->ops->apply = PCApply_SMG; 32871c188c59Sftrigaux pc->ops->applyrichardson = PCApplyRichardson_SMG; 32881c188c59Sftrigaux pc->ops->setup = PCSetUp_SMG; 32891c188c59Sftrigaux 32901c188c59Sftrigaux PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 3291ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 32921c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 32933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32941c188c59Sftrigaux } 3295