116d9e3a6SLisandro Dalcin /* 216d9e3a6SLisandro Dalcin Provides an interface to the LLNL package hypre 316d9e3a6SLisandro Dalcin */ 40f1074feSSatish Balay 5589dcaf0SStefano Zampini #include <petscpkg_version.h> 6af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/ 749a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */ 849a781f5SStefano Zampini #include <petsc/private/matimpl.h> 96ea7df73SStefano Zampini #include <petsc/private/vecimpl.h> 1058968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h> 1149a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h> 12c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h> 134cb006feSStefano Zampini #include <_hypre_parcsr_ls.h> 148a2c336bSFande Kong #include <petscmathypre.h> 1516d9e3a6SLisandro Dalcin 16a4af0ceeSJacob Faibussowitsch #if defined(PETSC_HAVE_HYPRE_DEVICE) 17a4af0ceeSJacob Faibussowitsch #include <petsc/private/deviceimpl.h> 18a4af0ceeSJacob Faibussowitsch #endif 19a4af0ceeSJacob Faibussowitsch 20dff31646SBarry Smith static PetscBool cite = PETSC_FALSE; 219371c9d4SSatish Balay static const char hypreCitation[] = "@manual{hypre-web-page,\n title = {{\\sl hypre}: High Performance Preconditioners},\n organization = {Lawrence Livermore National Laboratory},\n note = " 22bd87328aSJed Brown "{\\url{https://www.llnl.gov/casc/hypre}}\n}\n"; 231f817a21SBarry Smith 2416d9e3a6SLisandro Dalcin /* 2516d9e3a6SLisandro Dalcin Private context (data structure) for the preconditioner. 2616d9e3a6SLisandro Dalcin */ 2716d9e3a6SLisandro Dalcin typedef struct { 2816d9e3a6SLisandro Dalcin HYPRE_Solver hsolver; 2949a781f5SStefano Zampini Mat hpmat; /* MatHYPRE */ 3016d9e3a6SLisandro Dalcin 314ddd07fcSJed Brown HYPRE_Int (*destroy)(HYPRE_Solver); 324ddd07fcSJed Brown HYPRE_Int (*solve)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector); 334ddd07fcSJed Brown HYPRE_Int (*setup)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector); 3416d9e3a6SLisandro Dalcin 3516d9e3a6SLisandro Dalcin MPI_Comm comm_hypre; 3616d9e3a6SLisandro Dalcin char *hypre_type; 3716d9e3a6SLisandro Dalcin 3816d9e3a6SLisandro Dalcin /* options for Pilut and BoomerAMG*/ 394ddd07fcSJed Brown PetscInt maxiter; 4039accc25SStefano Zampini PetscReal tol; 4116d9e3a6SLisandro Dalcin 4216d9e3a6SLisandro Dalcin /* options for Pilut */ 434ddd07fcSJed Brown PetscInt factorrowsize; 4416d9e3a6SLisandro Dalcin 4516d9e3a6SLisandro Dalcin /* options for ParaSails */ 464ddd07fcSJed Brown PetscInt nlevels; 478966356dSPierre Jolivet PetscReal threshold; 4839accc25SStefano Zampini PetscReal filter; 4939accc25SStefano Zampini PetscReal loadbal; 504ddd07fcSJed Brown PetscInt logging; 514ddd07fcSJed Brown PetscInt ruse; 524ddd07fcSJed Brown PetscInt symt; 5316d9e3a6SLisandro Dalcin 5422b6d1caSBarry Smith /* options for BoomerAMG */ 55ace3abfcSBarry Smith PetscBool printstatistics; 5616d9e3a6SLisandro Dalcin 5716d9e3a6SLisandro Dalcin /* options for BoomerAMG */ 584ddd07fcSJed Brown PetscInt cycletype; 594ddd07fcSJed Brown PetscInt maxlevels; 6039accc25SStefano Zampini PetscReal strongthreshold; 6139accc25SStefano Zampini PetscReal maxrowsum; 624ddd07fcSJed Brown PetscInt gridsweeps[3]; 634ddd07fcSJed Brown PetscInt coarsentype; 644ddd07fcSJed Brown PetscInt measuretype; 656a251517SEike Mueller PetscInt smoothtype; 668131ecf7SEike Mueller PetscInt smoothnumlevels; 67ec64516dSEike Mueller PetscInt eu_level; /* Number of levels for ILU(k) in Euclid */ 6839accc25SStefano Zampini PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */ 69ec64516dSEike Mueller PetscInt eu_bj; /* Defines use of Block Jacobi ILU in Euclid */ 704ddd07fcSJed Brown PetscInt relaxtype[3]; 7139accc25SStefano Zampini PetscReal relaxweight; 7239accc25SStefano Zampini PetscReal outerrelaxweight; 734ddd07fcSJed Brown PetscInt relaxorder; 7439accc25SStefano Zampini PetscReal truncfactor; 75ace3abfcSBarry Smith PetscBool applyrichardson; 764ddd07fcSJed Brown PetscInt pmax; 774ddd07fcSJed Brown PetscInt interptype; 78589dcaf0SStefano Zampini PetscInt maxc; 79589dcaf0SStefano Zampini PetscInt minc; 80db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 81db6f9c32SMark Adams char *spgemm_type; // this is a global hypre parameter but is closely associated with BoomerAMG 82db6f9c32SMark Adams #endif 836ea7df73SStefano Zampini /* GPU */ 846ea7df73SStefano Zampini PetscBool keeptranspose; 856ea7df73SStefano Zampini PetscInt rap2; 866ea7df73SStefano Zampini PetscInt mod_rap2; 876ea7df73SStefano Zampini 88589dcaf0SStefano Zampini /* AIR */ 89589dcaf0SStefano Zampini PetscInt Rtype; 90589dcaf0SStefano Zampini PetscReal Rstrongthreshold; 91589dcaf0SStefano Zampini PetscReal Rfilterthreshold; 92589dcaf0SStefano Zampini PetscInt Adroptype; 93589dcaf0SStefano Zampini PetscReal Adroptol; 94589dcaf0SStefano Zampini 954ddd07fcSJed Brown PetscInt agg_nl; 966ea7df73SStefano Zampini PetscInt agg_interptype; 974ddd07fcSJed Brown PetscInt agg_num_paths; 98ace3abfcSBarry Smith PetscBool nodal_relax; 994ddd07fcSJed Brown PetscInt nodal_relax_levels; 1004cb006feSStefano Zampini 1015272c319SBarry Smith PetscInt nodal_coarsening; 10222e51d31SStefano Zampini PetscInt nodal_coarsening_diag; 1035272c319SBarry Smith PetscInt vec_interp_variant; 10422e51d31SStefano Zampini PetscInt vec_interp_qmax; 10522e51d31SStefano Zampini PetscBool vec_interp_smooth; 10622e51d31SStefano Zampini PetscInt interp_refine; 10722e51d31SStefano Zampini 1086ea7df73SStefano Zampini /* NearNullSpace support */ 1096ea7df73SStefano Zampini VecHYPRE_IJVector *hmnull; 1106ea7df73SStefano Zampini HYPRE_ParVector *phmnull; 1115272c319SBarry Smith PetscInt n_hmnull; 1125272c319SBarry Smith Vec hmnull_constant; 1135272c319SBarry Smith 114863406b8SStefano Zampini /* options for AS (Auxiliary Space preconditioners) */ 115863406b8SStefano Zampini PetscInt as_print; 116863406b8SStefano Zampini PetscInt as_max_iter; 117863406b8SStefano Zampini PetscReal as_tol; 118863406b8SStefano Zampini PetscInt as_relax_type; 119863406b8SStefano Zampini PetscInt as_relax_times; 120863406b8SStefano Zampini PetscReal as_relax_weight; 121863406b8SStefano Zampini PetscReal as_omega; 122863406b8SStefano Zampini PetscInt as_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson (AMS) or Curl problem (ADS) */ 123863406b8SStefano Zampini PetscReal as_amg_alpha_theta; /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */ 124863406b8SStefano Zampini PetscInt as_amg_beta_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson (AMS) or vector Poisson (ADS) */ 125863406b8SStefano Zampini PetscReal as_amg_beta_theta; /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS) */ 1264cb006feSStefano Zampini PetscInt ams_cycle_type; 127863406b8SStefano Zampini PetscInt ads_cycle_type; 1284cb006feSStefano Zampini 1294cb006feSStefano Zampini /* additional data */ 1305ac14e1cSStefano Zampini Mat G; /* MatHYPRE */ 1315ac14e1cSStefano Zampini Mat C; /* MatHYPRE */ 1325ac14e1cSStefano Zampini Mat alpha_Poisson; /* MatHYPRE */ 1335ac14e1cSStefano Zampini Mat beta_Poisson; /* MatHYPRE */ 1345ac14e1cSStefano Zampini 1355ac14e1cSStefano Zampini /* extra information for AMS */ 1365ac14e1cSStefano Zampini PetscInt dim; /* geometrical dimension */ 1376ea7df73SStefano Zampini VecHYPRE_IJVector coords[3]; 1386ea7df73SStefano Zampini VecHYPRE_IJVector constants[3]; 139be14dc20SKerry Key VecHYPRE_IJVector interior; 1406bf688a0SCe Qin Mat RT_PiFull, RT_Pi[3]; 1416bf688a0SCe Qin Mat ND_PiFull, ND_Pi[3]; 1424cb006feSStefano Zampini PetscBool ams_beta_is_zero; 14323df4f25SStefano Zampini PetscBool ams_beta_is_zero_part; 14423df4f25SStefano Zampini PetscInt ams_proj_freq; 14516d9e3a6SLisandro Dalcin } PC_HYPRE; 14616d9e3a6SLisandro Dalcin 147d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREGetSolver(PC pc, HYPRE_Solver *hsolver) 148d71ae5a4SJacob Faibussowitsch { 149d2128fa2SBarry Smith PC_HYPRE *jac = (PC_HYPRE *)pc->data; 150d2128fa2SBarry Smith 151d2128fa2SBarry Smith PetscFunctionBegin; 152d2128fa2SBarry Smith *hsolver = jac->hsolver; 1533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 154d2128fa2SBarry Smith } 15516d9e3a6SLisandro Dalcin 156fd2dd295SFande Kong /* 1578a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1588a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1598a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 160fd2dd295SFande Kong */ 161d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc, PetscInt *nlevels, Mat *operators[]) 162d71ae5a4SJacob Faibussowitsch { 1638a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1648a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1658a2c336bSFande Kong PetscInt num_levels, l; 1668a2c336bSFande Kong Mat *mattmp; 1678a2c336bSFande Kong hypre_ParCSRMatrix **A_array; 1688a2c336bSFande Kong 1698a2c336bSFande Kong PetscFunctionBegin; 1709566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same)); 1715f80ce2aSJacob Faibussowitsch PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG "); 1728a2c336bSFande Kong num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)(jac->hsolver)); 1739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels, &mattmp)); 1748a2c336bSFande Kong A_array = hypre_ParAMGDataAArray((hypre_ParAMGData *)(jac->hsolver)); 1758a2c336bSFande Kong for (l = 1; l < num_levels; l++) { 1769566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(A_array[l], MATAIJ, PETSC_OWN_POINTER, &(mattmp[num_levels - 1 - l]))); 1778a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 1788a2c336bSFande Kong A_array[l] = NULL; 1798a2c336bSFande Kong } 1808a2c336bSFande Kong *nlevels = num_levels; 1818a2c336bSFande Kong *operators = mattmp; 1823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1838a2c336bSFande Kong } 1848a2c336bSFande Kong 185fd2dd295SFande Kong /* 1868a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1878a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1888a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 189fd2dd295SFande Kong */ 190d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc, PetscInt *nlevels, Mat *interpolations[]) 191d71ae5a4SJacob Faibussowitsch { 1928a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1938a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1948a2c336bSFande Kong PetscInt num_levels, l; 1958a2c336bSFande Kong Mat *mattmp; 1968a2c336bSFande Kong hypre_ParCSRMatrix **P_array; 1978a2c336bSFande Kong 1988a2c336bSFande Kong PetscFunctionBegin; 1999566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same)); 2005f80ce2aSJacob Faibussowitsch PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG "); 2018a2c336bSFande Kong num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)(jac->hsolver)); 2029566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels, &mattmp)); 2038a2c336bSFande Kong P_array = hypre_ParAMGDataPArray((hypre_ParAMGData *)(jac->hsolver)); 2048a2c336bSFande Kong for (l = 1; l < num_levels; l++) { 2059566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(P_array[num_levels - 1 - l], MATAIJ, PETSC_OWN_POINTER, &(mattmp[l - 1]))); 2068a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 2078a2c336bSFande Kong P_array[num_levels - 1 - l] = NULL; 2088a2c336bSFande Kong } 2098a2c336bSFande Kong *nlevels = num_levels; 2108a2c336bSFande Kong *interpolations = mattmp; 2113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2128a2c336bSFande Kong } 2138a2c336bSFande Kong 214ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */ 215d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc) 216d71ae5a4SJacob Faibussowitsch { 217ce6a8a0dSJed Brown PC_HYPRE *jac = (PC_HYPRE *)pc->data; 218ce6a8a0dSJed Brown PetscInt i; 219ce6a8a0dSJed Brown 2209d678128SJed Brown PetscFunctionBegin; 22148a46eb9SPierre Jolivet for (i = 0; i < jac->n_hmnull; i++) PetscCall(VecHYPRE_IJVectorDestroy(&jac->hmnull[i])); 2229566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hmnull)); 2239566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->phmnull)); 2249566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->hmnull_constant)); 2259d678128SJed Brown jac->n_hmnull = 0; 2263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 227ce6a8a0dSJed Brown } 228ce6a8a0dSJed Brown 229d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_HYPRE(PC pc) 230d71ae5a4SJacob Faibussowitsch { 23116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 23249a781f5SStefano Zampini Mat_HYPRE *hjac; 23316d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 23416d9e3a6SLisandro Dalcin HYPRE_ParVector bv, xv; 23549a781f5SStefano Zampini PetscBool ishypre; 23616d9e3a6SLisandro Dalcin 23716d9e3a6SLisandro Dalcin PetscFunctionBegin; 23848a46eb9SPierre Jolivet if (!jac->hypre_type) PetscCall(PCHYPRESetType(pc, "boomeramg")); 2395f5c5b43SBarry Smith 2409566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRE, &ishypre)); 24149a781f5SStefano Zampini if (!ishypre) { 2429566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 2439566063dSJacob Faibussowitsch PetscCall(MatConvert(pc->pmat, MATHYPRE, MAT_INITIAL_MATRIX, &jac->hpmat)); 24449a781f5SStefano Zampini } else { 2459566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc->pmat)); 2469566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 24749a781f5SStefano Zampini jac->hpmat = pc->pmat; 24816d9e3a6SLisandro Dalcin } 2496ea7df73SStefano Zampini /* allow debug */ 2509566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(jac->hpmat, NULL, "-pc_hypre_mat_view")); 25149a781f5SStefano Zampini hjac = (Mat_HYPRE *)(jac->hpmat->data); 2525f5c5b43SBarry Smith 25316d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 25416d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 2555272c319SBarry Smith MatNullSpace mnull; 2565272c319SBarry Smith PetscBool has_const; 25749a781f5SStefano Zampini PetscInt bs, nvec, i; 2585272c319SBarry Smith const Vec *vecs; 2595272c319SBarry Smith 2609566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat, &bs)); 261792fecdfSBarry Smith if (bs > 1) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 2629566063dSJacob Faibussowitsch PetscCall(MatGetNearNullSpace(pc->mat, &mnull)); 2635272c319SBarry Smith if (mnull) { 2649566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 2659566063dSJacob Faibussowitsch PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs)); 2669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->hmnull)); 2679566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->phmnull)); 2685272c319SBarry Smith for (i = 0; i < nvec; i++) { 2699566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map, &jac->hmnull[i])); 2709566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(vecs[i], jac->hmnull[i])); 271792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[i]->ij, (void **)&jac->phmnull[i]); 2725272c319SBarry Smith } 2735272c319SBarry Smith if (has_const) { 2749566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(pc->pmat, &jac->hmnull_constant, NULL)); 2759566063dSJacob Faibussowitsch PetscCall(VecSet(jac->hmnull_constant, 1)); 2769566063dSJacob Faibussowitsch PetscCall(VecNormalize(jac->hmnull_constant, NULL)); 2779566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map, &jac->hmnull[nvec])); 2789566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant, jac->hmnull[nvec])); 279792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[nvec]->ij, (void **)&jac->phmnull[nvec]); 2805272c319SBarry Smith nvec++; 2815272c319SBarry Smith } 282792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVectors, jac->hsolver, nvec, jac->phmnull); 2835272c319SBarry Smith jac->n_hmnull = nvec; 2845272c319SBarry Smith } 2854cb006feSStefano Zampini } 286863406b8SStefano Zampini 2874cb006feSStefano Zampini /* special case for AMS */ 2884cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 2895ac14e1cSStefano Zampini Mat_HYPRE *hm; 2905ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 2916bf688a0SCe Qin if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 292f1580f4eSBarry 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()"); 2936bf688a0SCe Qin } 29448a46eb9SPierre Jolivet if (jac->dim) PetscCallExternal(HYPRE_AMSSetDimension, jac->hsolver, jac->dim); 2955ac14e1cSStefano Zampini if (jac->constants[0]) { 2965ac14e1cSStefano Zampini HYPRE_ParVector ozz, zoz, zzo = NULL; 297792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[0]->ij, (void **)(&ozz)); 298792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[1]->ij, (void **)(&zoz)); 29948a46eb9SPierre Jolivet if (jac->constants[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[2]->ij, (void **)(&zzo)); 300792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetEdgeConstantVectors, jac->hsolver, ozz, zoz, zzo); 3015ac14e1cSStefano Zampini } 3025ac14e1cSStefano Zampini if (jac->coords[0]) { 3035ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3045ac14e1cSStefano Zampini coords[0] = NULL; 3055ac14e1cSStefano Zampini coords[1] = NULL; 3065ac14e1cSStefano Zampini coords[2] = NULL; 307792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 308792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 309792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 310792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 3115ac14e1cSStefano Zampini } 3125f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3135ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->G->data); 314792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 315792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDiscreteGradient, jac->hsolver, parcsr); 3165ac14e1cSStefano Zampini if (jac->alpha_Poisson) { 3175ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->alpha_Poisson->data); 318792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 319792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaPoissonMatrix, jac->hsolver, parcsr); 3205ac14e1cSStefano Zampini } 3215ac14e1cSStefano Zampini if (jac->ams_beta_is_zero) { 322792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, NULL); 3235ac14e1cSStefano Zampini } else if (jac->beta_Poisson) { 3245ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->beta_Poisson->data); 325792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 326792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, parcsr); 327be14dc20SKerry Key } else if (jac->ams_beta_is_zero_part) { 328be14dc20SKerry Key if (jac->interior) { 329be14dc20SKerry Key HYPRE_ParVector interior = NULL; 330be14dc20SKerry Key PetscCallExternal(HYPRE_IJVectorGetObject, jac->interior->ij, (void **)(&interior)); 331be14dc20SKerry Key PetscCallExternal(HYPRE_AMSSetInteriorNodes, jac->hsolver, interior); 332be14dc20SKerry Key } else { 333be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 334be14dc20SKerry Key } 3355ac14e1cSStefano Zampini } 3366bf688a0SCe Qin if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) { 3376bf688a0SCe Qin PetscInt i; 3386bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3396bf688a0SCe Qin if (jac->ND_PiFull) { 3406bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->ND_PiFull->data); 341792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 3426bf688a0SCe Qin } else { 3436bf688a0SCe Qin nd_parcsrfull = NULL; 3446bf688a0SCe Qin } 3456bf688a0SCe Qin for (i = 0; i < 3; ++i) { 3466bf688a0SCe Qin if (jac->ND_Pi[i]) { 3476bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->ND_Pi[i]->data); 348792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 3496bf688a0SCe Qin } else { 3506bf688a0SCe Qin nd_parcsr[i] = NULL; 3516bf688a0SCe Qin } 3526bf688a0SCe Qin } 353792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetInterpolations, jac->hsolver, nd_parcsrfull, nd_parcsr[0], nd_parcsr[1], nd_parcsr[2]); 3546bf688a0SCe Qin } 3554cb006feSStefano Zampini } 356863406b8SStefano Zampini /* special case for ADS */ 357863406b8SStefano Zampini if (jac->setup == HYPRE_ADSSetup) { 3585ac14e1cSStefano Zampini Mat_HYPRE *hm; 3595ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 3606bf688a0SCe 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])))) { 3616bf688a0SCe Qin SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations"); 3629371c9d4SSatish 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"); 3635f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3645f80ce2aSJacob Faibussowitsch PetscCheck(jac->C, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient"); 3655ac14e1cSStefano Zampini if (jac->coords[0]) { 3665ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3675ac14e1cSStefano Zampini coords[0] = NULL; 3685ac14e1cSStefano Zampini coords[1] = NULL; 3695ac14e1cSStefano Zampini coords[2] = NULL; 370792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 371792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 372792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 373792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 3745ac14e1cSStefano Zampini } 3755ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->G->data); 376792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 377792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteGradient, jac->hsolver, parcsr); 3785ac14e1cSStefano Zampini hm = (Mat_HYPRE *)(jac->C->data); 379792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 380792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteCurl, jac->hsolver, parcsr); 3816bf688a0SCe Qin if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 3826bf688a0SCe Qin PetscInt i; 3836bf688a0SCe Qin HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3]; 3846bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3856bf688a0SCe Qin if (jac->RT_PiFull) { 3866bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->RT_PiFull->data); 387792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsrfull)); 3886bf688a0SCe Qin } else { 3896bf688a0SCe Qin rt_parcsrfull = NULL; 3906bf688a0SCe Qin } 3916bf688a0SCe Qin for (i = 0; i < 3; ++i) { 3926bf688a0SCe Qin if (jac->RT_Pi[i]) { 3936bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->RT_Pi[i]->data); 394792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsr[i])); 3956bf688a0SCe Qin } else { 3966bf688a0SCe Qin rt_parcsr[i] = NULL; 3976bf688a0SCe Qin } 3986bf688a0SCe Qin } 3996bf688a0SCe Qin if (jac->ND_PiFull) { 4006bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->ND_PiFull->data); 401792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 4026bf688a0SCe Qin } else { 4036bf688a0SCe Qin nd_parcsrfull = NULL; 4046bf688a0SCe Qin } 4056bf688a0SCe Qin for (i = 0; i < 3; ++i) { 4066bf688a0SCe Qin if (jac->ND_Pi[i]) { 4076bf688a0SCe Qin hm = (Mat_HYPRE *)(jac->ND_Pi[i]->data); 408792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 4096bf688a0SCe Qin } else { 4106bf688a0SCe Qin nd_parcsr[i] = NULL; 4116bf688a0SCe Qin } 4126bf688a0SCe Qin } 413792fecdfSBarry 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]); 4146bf688a0SCe Qin } 415863406b8SStefano Zampini } 416792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 417792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&bv); 418792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&xv); 41997c1e3cbSStefano Zampini PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 420792fecdfSBarry Smith PetscCallExternal(jac->setup, jac->hsolver, hmat, bv, xv); 42197c1e3cbSStefano Zampini PetscCall(PetscFPTrapPop()); 4223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42316d9e3a6SLisandro Dalcin } 42416d9e3a6SLisandro Dalcin 425d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_HYPRE(PC pc, Vec b, Vec x) 426d71ae5a4SJacob Faibussowitsch { 42716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 42849a781f5SStefano Zampini Mat_HYPRE *hjac = (Mat_HYPRE *)(jac->hpmat->data); 42916d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 43016d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 43116d9e3a6SLisandro Dalcin 43216d9e3a6SLisandro Dalcin PetscFunctionBegin; 4339566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 4349566063dSJacob Faibussowitsch if (!jac->applyrichardson) PetscCall(VecSet(x, 0.0)); 4359566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b, b)); 4369566063dSJacob Faibussowitsch if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x, x)); 4379566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x, x)); 438792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 439792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 440792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 4419371c9d4SSatish Balay PetscStackCallExternalVoid( 4429371c9d4SSatish Balay "Hypre solve", do { 4435f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = (*jac->solve)(jac->hsolver, hmat, jbv, jxv); 4445f80ce2aSJacob Faibussowitsch if (hierr) { 4455f80ce2aSJacob Faibussowitsch PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 44685245615SPierre Jolivet HYPRE_ClearAllErrors(); 4475f80ce2aSJacob Faibussowitsch } 4485f80ce2aSJacob Faibussowitsch } while (0)); 44916d9e3a6SLisandro Dalcin 45048a46eb9SPierre Jolivet if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) PetscCallExternal(HYPRE_AMSProjectOutGradients, jac->hsolver, jxv); 4519566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 4529566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 4533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45416d9e3a6SLisandro Dalcin } 45516d9e3a6SLisandro Dalcin 45685245615SPierre Jolivet static PetscErrorCode PCMatApply_HYPRE_BoomerAMG(PC pc, Mat B, Mat X) 45785245615SPierre Jolivet { 45885245615SPierre Jolivet PC_HYPRE *jac = (PC_HYPRE *)pc->data; 45985245615SPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)(jac->hpmat->data); 46085245615SPierre Jolivet hypre_ParCSRMatrix *par_matrix; 46185245615SPierre Jolivet HYPRE_ParVector hb, hx; 46285245615SPierre Jolivet const PetscScalar *b; 46385245615SPierre Jolivet PetscScalar *x; 46485245615SPierre Jolivet PetscInt m, N, lda; 46585245615SPierre Jolivet hypre_Vector *x_local; 46685245615SPierre Jolivet PetscMemType type; 46785245615SPierre Jolivet 46885245615SPierre Jolivet PetscFunctionBegin; 46985245615SPierre Jolivet PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 47085245615SPierre Jolivet PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&par_matrix); 47185245615SPierre Jolivet PetscCall(MatGetLocalSize(B, &m, NULL)); 47285245615SPierre Jolivet PetscCall(MatGetSize(B, NULL, &N)); 47385245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hb); 47485245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hx); 47585245615SPierre Jolivet PetscCall(MatZeroEntries(X)); 47685245615SPierre Jolivet PetscCall(MatDenseGetArrayReadAndMemType(B, &b, &type)); 47785245615SPierre Jolivet PetscCall(MatDenseGetLDA(B, &lda)); 47885245615SPierre 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); 47985245615SPierre Jolivet PetscCall(MatDenseGetLDA(X, &lda)); 48085245615SPierre 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); 48185245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hb); 48285245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 48385245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)b; 48485245615SPierre Jolivet PetscCall(MatDenseGetArrayWriteAndMemType(X, &x, NULL)); 48585245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hx); 48685245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 48785245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)x; 48885245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hb, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 48985245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hx, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 49085245615SPierre Jolivet PetscStackCallExternalVoid( 49185245615SPierre Jolivet "Hypre solve", do { 49285245615SPierre Jolivet HYPRE_Int hierr = (*jac->solve)(jac->hsolver, par_matrix, hb, hx); 49385245615SPierre Jolivet if (hierr) { 49485245615SPierre Jolivet PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 49585245615SPierre Jolivet HYPRE_ClearAllErrors(); 49685245615SPierre Jolivet } 49785245615SPierre Jolivet } while (0)); 49885245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hb); 49985245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hx); 50085245615SPierre Jolivet PetscCall(MatDenseRestoreArrayReadAndMemType(B, &b)); 50185245615SPierre Jolivet PetscCall(MatDenseRestoreArrayWriteAndMemType(X, &x)); 50285245615SPierre Jolivet PetscFunctionReturn(PETSC_SUCCESS); 50385245615SPierre Jolivet } 50485245615SPierre Jolivet 505d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_HYPRE(PC pc) 506d71ae5a4SJacob Faibussowitsch { 5078695de01SBarry Smith PC_HYPRE *jac = (PC_HYPRE *)pc->data; 5088695de01SBarry Smith 5098695de01SBarry Smith PetscFunctionBegin; 5109566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 5119566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 5129566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 5139566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 5149566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 5159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 5169566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[0])); 5179566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[1])); 5189566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[2])); 5199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 5209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[0])); 5219566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[1])); 5229566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[2])); 5239566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 5249566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 5259566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 5269566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 5279566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 5289566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 529be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 5309566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 5315ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 532be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 5335ac14e1cSStefano Zampini jac->dim = 0; 5343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5358695de01SBarry Smith } 5368695de01SBarry Smith 537d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_HYPRE(PC pc) 538d71ae5a4SJacob Faibussowitsch { 53916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 54016d9e3a6SLisandro Dalcin 54116d9e3a6SLisandro Dalcin PetscFunctionBegin; 5429566063dSJacob Faibussowitsch PetscCall(PCReset_HYPRE(pc)); 543792fecdfSBarry Smith if (jac->destroy) PetscCallExternal(jac->destroy, jac->hsolver); 5449566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 545db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 5469566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->spgemm_type)); 547db6f9c32SMark Adams #endif 5489566063dSJacob Faibussowitsch if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 5499566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 55016d9e3a6SLisandro Dalcin 5519566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc, 0)); 5529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", NULL)); 5539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", NULL)); 5549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", NULL)); 5559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", NULL)); 5569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", NULL)); 5579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetConstantEdgeVectors_C", NULL)); 5589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", NULL)); 5592e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", NULL)); 560be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", NULL)); 5619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", NULL)); 5629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", NULL)); 5639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", NULL)); 5649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", NULL)); 5652e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", NULL)); 5663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56716d9e3a6SLisandro Dalcin } 56816d9e3a6SLisandro Dalcin 569d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc, PetscOptionItems *PetscOptionsObject) 570d71ae5a4SJacob Faibussowitsch { 57116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 572ace3abfcSBarry Smith PetscBool flag; 57316d9e3a6SLisandro Dalcin 57416d9e3a6SLisandro Dalcin PetscFunctionBegin; 575d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Pilut Options"); 5769566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter", "Number of iterations", "None", jac->maxiter, &jac->maxiter, &flag)); 577792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetMaxIter, jac->hsolver, jac->maxiter); 5789566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol", "Drop tolerance", "None", jac->tol, &jac->tol, &flag)); 579792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetDropTolerance, jac->hsolver, jac->tol); 5809566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize", "FactorRowSize", "None", jac->factorrowsize, &jac->factorrowsize, &flag)); 581792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetFactorRowSize, jac->hsolver, jac->factorrowsize); 582d0609cedSBarry Smith PetscOptionsHeadEnd(); 5833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58416d9e3a6SLisandro Dalcin } 58516d9e3a6SLisandro Dalcin 586d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Pilut(PC pc, PetscViewer viewer) 587d71ae5a4SJacob Faibussowitsch { 58816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 589ace3abfcSBarry Smith PetscBool iascii; 59016d9e3a6SLisandro Dalcin 59116d9e3a6SLisandro Dalcin PetscFunctionBegin; 5929566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 59316d9e3a6SLisandro Dalcin if (iascii) { 5949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Pilut preconditioning\n")); 59516d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 59663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum number of iterations %" PetscInt_FMT "\n", jac->maxiter)); 59716d9e3a6SLisandro Dalcin } else { 5989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default maximum number of iterations \n")); 59916d9e3a6SLisandro Dalcin } 60016d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 6019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->tol)); 60216d9e3a6SLisandro Dalcin } else { 6039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default drop tolerance \n")); 60416d9e3a6SLisandro Dalcin } 60516d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 60663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factor row size %" PetscInt_FMT "\n", jac->factorrowsize)); 60716d9e3a6SLisandro Dalcin } else { 6089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factor row size \n")); 60916d9e3a6SLisandro Dalcin } 61016d9e3a6SLisandro Dalcin } 6113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 61216d9e3a6SLisandro Dalcin } 61316d9e3a6SLisandro Dalcin 614d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc, PetscOptionItems *PetscOptionsObject) 615d71ae5a4SJacob Faibussowitsch { 616db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 6178bf83915SBarry Smith PetscBool flag, eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE; 618db966c6cSHong Zhang 619db966c6cSHong Zhang PetscFunctionBegin; 620d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Euclid Options"); 6219566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_euclid_level", "Factorization levels", "None", jac->eu_level, &jac->eu_level, &flag)); 622792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_EuclidSetLevel, jac->hsolver, jac->eu_level); 6238bf83915SBarry Smith 6249566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_euclid_droptolerance", "Drop tolerance for ILU(k) in Euclid", "None", jac->eu_droptolerance, &jac->eu_droptolerance, &flag)); 6258bf83915SBarry Smith if (flag) { 6268bf83915SBarry Smith PetscMPIInt size; 6278bf83915SBarry Smith 6289566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc), &size)); 6297827d75bSBarry Smith PetscCheck(size == 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "hypre's Euclid does not support a parallel drop tolerance"); 630792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetILUT, jac->hsolver, jac->eu_droptolerance); 6318bf83915SBarry Smith } 6328bf83915SBarry Smith 6339566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj, &eu_bj, &flag)); 6348bf83915SBarry Smith if (flag) { 6358bf83915SBarry Smith jac->eu_bj = eu_bj ? 1 : 0; 636792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetBJ, jac->hsolver, jac->eu_bj); 6378bf83915SBarry Smith } 638d0609cedSBarry Smith PetscOptionsHeadEnd(); 6393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 640db966c6cSHong Zhang } 641db966c6cSHong Zhang 642d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Euclid(PC pc, PetscViewer viewer) 643d71ae5a4SJacob Faibussowitsch { 644db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 645db966c6cSHong Zhang PetscBool iascii; 646db966c6cSHong Zhang 647db966c6cSHong Zhang PetscFunctionBegin; 6489566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 649db966c6cSHong Zhang if (iascii) { 6509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Euclid preconditioning\n")); 651db966c6cSHong Zhang if (jac->eu_level != PETSC_DEFAULT) { 65263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factorization levels %" PetscInt_FMT "\n", jac->eu_level)); 653db966c6cSHong Zhang } else { 6549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factorization levels \n")); 655db966c6cSHong Zhang } 6569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->eu_droptolerance)); 65763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 658db966c6cSHong Zhang } 6593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 660db966c6cSHong Zhang } 661db966c6cSHong Zhang 662d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc, Vec b, Vec x) 663d71ae5a4SJacob Faibussowitsch { 66416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 66549a781f5SStefano Zampini Mat_HYPRE *hjac = (Mat_HYPRE *)(jac->hpmat->data); 66616d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 66716d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 66816d9e3a6SLisandro Dalcin 66916d9e3a6SLisandro Dalcin PetscFunctionBegin; 6709566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 6719566063dSJacob Faibussowitsch PetscCall(VecSet(x, 0.0)); 6729566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->x, b)); 6739566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->b, x)); 67416d9e3a6SLisandro Dalcin 675792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 676792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 677792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 67816d9e3a6SLisandro Dalcin 6799371c9d4SSatish Balay PetscStackCallExternalVoid( 6809371c9d4SSatish Balay "Hypre Transpose solve", do { 6815f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver, hmat, jbv, jxv); 6825f80ce2aSJacob Faibussowitsch if (hierr) { 68316d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 6845f80ce2aSJacob Faibussowitsch PetscCheck(hierr == 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 68585245615SPierre Jolivet HYPRE_ClearAllErrors(); 6865f80ce2aSJacob Faibussowitsch } 6875f80ce2aSJacob Faibussowitsch } while (0)); 68816d9e3a6SLisandro Dalcin 6899566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 6909566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 6913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 69216d9e3a6SLisandro Dalcin } 69316d9e3a6SLisandro Dalcin 694d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char name[]) 695d71ae5a4SJacob Faibussowitsch { 696db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 697db6f9c32SMark Adams PetscBool flag; 698db6f9c32SMark Adams 699db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 700db6f9c32SMark Adams PetscFunctionBegin; 701db6f9c32SMark Adams if (jac->spgemm_type) { 7029566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->spgemm_type, name, &flag)); 70328b400f6SJacob Faibussowitsch PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "Cannot reset the HYPRE SpGEMM (really we can)"); 7043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 705db6f9c32SMark Adams } else { 7069566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->spgemm_type)); 707db6f9c32SMark Adams } 7089566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("cusparse", jac->spgemm_type, &flag)); 709db6f9c32SMark Adams if (flag) { 710792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 1); 7113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 712db6f9c32SMark Adams } 7139566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("hypre", jac->spgemm_type, &flag)); 714db6f9c32SMark Adams if (flag) { 715792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 0); 7163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 717db6f9c32SMark Adams } 718db6f9c32SMark Adams jac->spgemm_type = NULL; 7192d6c3ceeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE SpGEMM type %s; Choices are cusparse, hypre", name); 720db6f9c32SMark Adams #endif 721db6f9c32SMark Adams } 722db6f9c32SMark Adams 723d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[]) 724d71ae5a4SJacob Faibussowitsch { 725db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 726db6f9c32SMark Adams 727db6f9c32SMark Adams PetscFunctionBegin; 728db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 729db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 730db6f9c32SMark Adams *spgemm = jac->spgemm_type; 731db6f9c32SMark Adams #endif 7323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 733db6f9c32SMark Adams } 734db6f9c32SMark Adams 73516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"", "V", "W"}; 7360f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP", "Ruge-Stueben", "", "modifiedRuge-Stueben", "", "", "Falgout", "", "PMIS", "", "HMIS"}; 73716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local", "global"}; 73865de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 7396a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[] = {"Schwarz-smoothers", "Pilut", "ParaSails", "Euclid"}; 7409371c9d4SSatish 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"}; 7419371c9d4SSatish 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"}; 742d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc, PetscOptionItems *PetscOptionsObject) 743d71ae5a4SJacob Faibussowitsch { 74416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 74522e51d31SStefano Zampini PetscInt bs, n, indx, level; 746ace3abfcSBarry Smith PetscBool flg, tmp_truth; 74716d9e3a6SLisandro Dalcin double tmpdbl, twodbl[2]; 748589dcaf0SStefano Zampini const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 749db6f9c32SMark Adams const char *PCHYPRESpgemmTypes[] = {"cusparse", "hypre"}; 75016d9e3a6SLisandro Dalcin 75116d9e3a6SLisandro Dalcin PetscFunctionBegin; 752d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE BoomerAMG Options"); 7539566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type", "Cycle type", "None", HYPREBoomerAMGCycleType + 1, 2, HYPREBoomerAMGCycleType[jac->cycletype], &indx, &flg)); 75416d9e3a6SLisandro Dalcin if (flg) { 7554336a9eeSBarry Smith jac->cycletype = indx + 1; 756792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 75716d9e3a6SLisandro Dalcin } 7589566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_levels", "Number of levels (of grids) allowed", "None", jac->maxlevels, &jac->maxlevels, &flg)); 75916d9e3a6SLisandro Dalcin if (flg) { 76063a3b9bcSJacob Faibussowitsch PetscCheck(jac->maxlevels >= 2, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Number of levels %" PetscInt_FMT " must be at least two", jac->maxlevels); 761792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 76216d9e3a6SLisandro Dalcin } 7639566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_iter", "Maximum iterations used PER hypre call", "None", jac->maxiter, &jac->maxiter, &flg)); 76416d9e3a6SLisandro Dalcin if (flg) { 76563a3b9bcSJacob Faibussowitsch PetscCheck(jac->maxiter >= 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Number of iterations %" PetscInt_FMT " must be at least one", jac->maxiter); 766792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 76716d9e3a6SLisandro Dalcin } 7689566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_tol", "Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)", "None", jac->tol, &jac->tol, &flg)); 76916d9e3a6SLisandro Dalcin if (flg) { 77008401ef6SPierre Jolivet PetscCheck(jac->tol >= 0.0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Tolerance %g must be greater than or equal to zero", (double)jac->tol); 771792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 77216d9e3a6SLisandro Dalcin } 77322e51d31SStefano Zampini bs = 1; 77448a46eb9SPierre Jolivet if (pc->pmat) PetscCall(MatGetBlockSize(pc->pmat, &bs)); 7759566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions", "Number of functions", "HYPRE_BoomerAMGSetNumFunctions", bs, &bs, &flg)); 77648a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 77716d9e3a6SLisandro Dalcin 7789566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_truncfactor", "Truncation factor for interpolation (0=no truncation)", "None", jac->truncfactor, &jac->truncfactor, &flg)); 77916d9e3a6SLisandro Dalcin if (flg) { 78008401ef6SPierre Jolivet PetscCheck(jac->truncfactor >= 0.0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Truncation factor %g must be great than or equal zero", (double)jac->truncfactor); 781792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 78216d9e3a6SLisandro Dalcin } 78316d9e3a6SLisandro Dalcin 7849566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_P_max", "Max elements per row for interpolation operator (0=unlimited)", "None", jac->pmax, &jac->pmax, &flg)); 7850f1074feSSatish Balay if (flg) { 78663a3b9bcSJacob Faibussowitsch PetscCheck(jac->pmax >= 0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "P_max %" PetscInt_FMT " must be greater than or equal to zero", jac->pmax); 787792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 7880f1074feSSatish Balay } 7890f1074feSSatish Balay 7909566063dSJacob 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)); 791792fecdfSBarry Smith if (flg) PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 7920f1074feSSatish Balay 7939566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_agg_num_paths", "Number of paths for aggressive coarsening", "None", jac->agg_num_paths, &jac->agg_num_paths, &flg)); 7940f1074feSSatish Balay if (flg) { 79563a3b9bcSJacob Faibussowitsch PetscCheck(jac->agg_num_paths >= 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Number of paths %" PetscInt_FMT " must be greater than or equal to 1", jac->agg_num_paths); 796792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 7970f1074feSSatish Balay } 7980f1074feSSatish Balay 7999566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold", "Threshold for being strongly connected", "None", jac->strongthreshold, &jac->strongthreshold, &flg)); 80016d9e3a6SLisandro Dalcin if (flg) { 80108401ef6SPierre Jolivet PetscCheck(jac->strongthreshold >= 0.0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Strong threshold %g must be great than or equal zero", (double)jac->strongthreshold); 802792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 80316d9e3a6SLisandro Dalcin } 8049566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum", "Maximum row sum", "None", jac->maxrowsum, &jac->maxrowsum, &flg)); 80516d9e3a6SLisandro Dalcin if (flg) { 80608401ef6SPierre Jolivet PetscCheck(jac->maxrowsum >= 0.0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Maximum row sum %g must be greater than zero", (double)jac->maxrowsum); 80708401ef6SPierre Jolivet PetscCheck(jac->maxrowsum <= 1.0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Maximum row sum %g must be less than or equal one", (double)jac->maxrowsum); 808792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 80916d9e3a6SLisandro Dalcin } 81016d9e3a6SLisandro Dalcin 81116d9e3a6SLisandro Dalcin /* Grid sweeps */ 8129566063dSJacob 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)); 81316d9e3a6SLisandro Dalcin if (flg) { 814792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps, jac->hsolver, indx); 81516d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 81616d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 8170f1074feSSatish Balay jac->gridsweeps[1] = indx; 8180f1074feSSatish Balay /*defaults coarse to 1 */ 8190f1074feSSatish Balay jac->gridsweeps[2] = 1; 82016d9e3a6SLisandro Dalcin } 8219566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen", "Use a nodal based coarsening 1-6", "HYPRE_BoomerAMGSetNodal", jac->nodal_coarsening, &jac->nodal_coarsening, &flg)); 82248a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodal, jac->hsolver, jac->nodal_coarsening); 8239566063dSJacob 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)); 82448a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodalDiag, jac->hsolver, jac->nodal_coarsening_diag); 8259566063dSJacob 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)); 82648a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecVariant, jac->hsolver, jac->vec_interp_variant); 8279566063dSJacob 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)); 82848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecQMax, jac->hsolver, jac->vec_interp_qmax); 8299566063dSJacob 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)); 83048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetSmoothInterpVectors, jac->hsolver, jac->vec_interp_smooth); 8319566063dSJacob 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)); 83248a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpRefine, jac->hsolver, jac->interp_refine); 8339566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down", "Number of sweeps for the down cycles", "None", jac->gridsweeps[0], &indx, &flg)); 83416d9e3a6SLisandro Dalcin if (flg) { 835792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 1); 8360f1074feSSatish Balay jac->gridsweeps[0] = indx; 83716d9e3a6SLisandro Dalcin } 8389566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up", "Number of sweeps for the up cycles", "None", jac->gridsweeps[1], &indx, &flg)); 83916d9e3a6SLisandro Dalcin if (flg) { 840792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 2); 8410f1074feSSatish Balay jac->gridsweeps[1] = indx; 84216d9e3a6SLisandro Dalcin } 8439566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse", "Number of sweeps for the coarse level", "None", jac->gridsweeps[2], &indx, &flg)); 84416d9e3a6SLisandro Dalcin if (flg) { 845792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 3); 8460f1074feSSatish Balay jac->gridsweeps[2] = indx; 84716d9e3a6SLisandro Dalcin } 84816d9e3a6SLisandro Dalcin 8496a251517SEike Mueller /* Smooth type */ 850dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type", "Enable more complex smoothers", "None", HYPREBoomerAMGSmoothType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType), HYPREBoomerAMGSmoothType[0], &indx, &flg)); 8516a251517SEike Mueller if (flg) { 8526a251517SEike Mueller jac->smoothtype = indx; 853792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, indx + 6); 8548131ecf7SEike Mueller jac->smoothnumlevels = 25; 855792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, 25); 8568131ecf7SEike Mueller } 8578131ecf7SEike Mueller 8588131ecf7SEike Mueller /* Number of smoothing levels */ 8599566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels", "Number of levels on which more complex smoothers are used", "None", 25, &indx, &flg)); 8608131ecf7SEike Mueller if (flg && (jac->smoothtype != -1)) { 8618131ecf7SEike Mueller jac->smoothnumlevels = indx; 862792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, indx); 8636a251517SEike Mueller } 8646a251517SEike Mueller 8651810e44eSEike Mueller /* Number of levels for ILU(k) for Euclid */ 8669566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level", "Number of levels for ILU(k) in Euclid smoother", "None", 0, &indx, &flg)); 8671810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8681810e44eSEike Mueller jac->eu_level = indx; 869792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, indx); 8701810e44eSEike Mueller } 8711810e44eSEike Mueller 8721810e44eSEike Mueller /* Filter for ILU(k) for Euclid */ 8731810e44eSEike Mueller double droptolerance; 8749566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance", "Drop tolerance for ILU(k) in Euclid smoother", "None", 0, &droptolerance, &flg)); 8751810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8761810e44eSEike Mueller jac->eu_droptolerance = droptolerance; 877792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, droptolerance); 8781810e44eSEike Mueller } 8791810e44eSEike Mueller 8801810e44eSEike Mueller /* Use Block Jacobi ILUT for Euclid */ 8819566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg)); 8821810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8831810e44eSEike Mueller jac->eu_bj = tmp_truth; 884792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuBJ, jac->hsolver, jac->eu_bj); 8851810e44eSEike Mueller } 8861810e44eSEike Mueller 88716d9e3a6SLisandro Dalcin /* Relax type */ 888dd39110bSPierre 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)); 88916d9e3a6SLisandro Dalcin if (flg) { 8900f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 891792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, indx); 8920f1074feSSatish Balay /* by default, coarse type set to 9 */ 8930f1074feSSatish Balay jac->relaxtype[2] = 9; 894792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, 9, 3); 89516d9e3a6SLisandro Dalcin } 896dd39110bSPierre 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)); 89716d9e3a6SLisandro Dalcin if (flg) { 89816d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 899792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 1); 90016d9e3a6SLisandro Dalcin } 901dd39110bSPierre 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)); 90216d9e3a6SLisandro Dalcin if (flg) { 9030f1074feSSatish Balay jac->relaxtype[1] = indx; 904792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 2); 90516d9e3a6SLisandro Dalcin } 906dd39110bSPierre 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)); 90716d9e3a6SLisandro Dalcin if (flg) { 9080f1074feSSatish Balay jac->relaxtype[2] = indx; 909792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 3); 91016d9e3a6SLisandro Dalcin } 91116d9e3a6SLisandro Dalcin 91216d9e3a6SLisandro Dalcin /* Relaxation Weight */ 9139566063dSJacob 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)); 91416d9e3a6SLisandro Dalcin if (flg) { 915792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxWt, jac->hsolver, tmpdbl); 91616d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 91716d9e3a6SLisandro Dalcin } 91816d9e3a6SLisandro Dalcin 91916d9e3a6SLisandro Dalcin n = 2; 92016d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 9219566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level", "Set the relaxation weight for a particular level (weight,level)", "None", twodbl, &n, &flg)); 92216d9e3a6SLisandro Dalcin if (flg) { 9230fdf79fbSJacob 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); 92416d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 925792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelRelaxWt, jac->hsolver, twodbl[0], indx); 92616d9e3a6SLisandro Dalcin } 92716d9e3a6SLisandro Dalcin 92816d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 9299566063dSJacob 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)); 93016d9e3a6SLisandro Dalcin if (flg) { 931792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOuterWt, jac->hsolver, tmpdbl); 93216d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 93316d9e3a6SLisandro Dalcin } 93416d9e3a6SLisandro Dalcin 93516d9e3a6SLisandro Dalcin n = 2; 93616d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 9379566063dSJacob 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)); 93816d9e3a6SLisandro Dalcin if (flg) { 9390fdf79fbSJacob 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); 94016d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 941792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelOuterWt, jac->hsolver, twodbl[0], indx); 94216d9e3a6SLisandro Dalcin } 94316d9e3a6SLisandro Dalcin 94416d9e3a6SLisandro Dalcin /* the Relax Order */ 9459566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg)); 94616d9e3a6SLisandro Dalcin 9478afaa268SBarry Smith if (flg && tmp_truth) { 94816d9e3a6SLisandro Dalcin jac->relaxorder = 0; 949792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 95016d9e3a6SLisandro Dalcin } 951dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type", "Measure type", "None", HYPREBoomerAMGMeasureType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType), HYPREBoomerAMGMeasureType[0], &indx, &flg)); 95216d9e3a6SLisandro Dalcin if (flg) { 95316d9e3a6SLisandro Dalcin jac->measuretype = indx; 954792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 95516d9e3a6SLisandro Dalcin } 9560f1074feSSatish Balay /* update list length 3/07 */ 957dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type", "Coarsen type", "None", HYPREBoomerAMGCoarsenType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType), HYPREBoomerAMGCoarsenType[6], &indx, &flg)); 95816d9e3a6SLisandro Dalcin if (flg) { 95916d9e3a6SLisandro Dalcin jac->coarsentype = indx; 960792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 96116d9e3a6SLisandro Dalcin } 9620f1074feSSatish Balay 9639566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg)); 96448a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 9659566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg)); 96648a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 967db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 968db6f9c32SMark Adams // global parameter but is closely associated with BoomerAMG 969dd39110bSPierre 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)); 9702d6c3ceeSStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 971db6f9c32SMark Adams if (!flg) indx = 0; 9729566063dSJacob Faibussowitsch PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, PCHYPRESpgemmTypes[indx])); 9732d6c3ceeSStefano Zampini #else 9742d6c3ceeSStefano Zampini PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, "hypre")); 9752d6c3ceeSStefano Zampini #endif 976db6f9c32SMark Adams #endif 977589dcaf0SStefano Zampini /* AIR */ 978589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 9799566063dSJacob 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)); 980792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 981589dcaf0SStefano Zampini if (jac->Rtype) { 982589dcaf0SStefano 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 */ 983589dcaf0SStefano Zampini 9849566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR", "Threshold for R", "None", jac->Rstrongthreshold, &jac->Rstrongthreshold, NULL)); 985792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 986589dcaf0SStefano Zampini 9879566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR", "Filter threshold for R", "None", jac->Rfilterthreshold, &jac->Rfilterthreshold, NULL)); 988792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 989589dcaf0SStefano Zampini 9909566063dSJacob 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)); 991792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 992589dcaf0SStefano Zampini 9939566063dSJacob 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)); 994792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 995589dcaf0SStefano Zampini } 996589dcaf0SStefano Zampini #endif 997589dcaf0SStefano Zampini 998ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9, 9, 9) 99963a3b9bcSJacob 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); 1000ecae95adSPierre Jolivet #endif 1001ecae95adSPierre Jolivet 10020f1074feSSatish Balay /* new 3/07 */ 1003dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type", "Interpolation type", "None", HYPREBoomerAMGInterpType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType), HYPREBoomerAMGInterpType[0], &indx, &flg)); 1004589dcaf0SStefano Zampini if (flg || jac->Rtype) { 1005589dcaf0SStefano Zampini if (flg) jac->interptype = indx; 1006792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 10070f1074feSSatish Balay } 10080f1074feSSatish Balay 10099566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", &flg)); 101016d9e3a6SLisandro Dalcin if (flg) { 1011b96a4a96SBarry Smith level = 3; 10129566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", level, &level, NULL)); 10132fa5cd67SKarl Rupp 1014b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1015792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel, jac->hsolver, level); 10162ae77aedSBarry Smith } 10172ae77aedSBarry Smith 10189566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", &flg)); 10192ae77aedSBarry Smith if (flg) { 1020b96a4a96SBarry Smith level = 3; 10219566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", level, &level, NULL)); 10222fa5cd67SKarl Rupp 1023b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1024792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDebugFlag, jac->hsolver, level); 102516d9e3a6SLisandro Dalcin } 10268f87f92bSBarry Smith 10279566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg)); 10288f87f92bSBarry Smith if (flg && tmp_truth) { 10298f87f92bSBarry Smith PetscInt tmp_int; 10309566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", jac->nodal_relax_levels, &tmp_int, &flg)); 10318f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 1032792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, 6); 1033792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDomainType, jac->hsolver, 1); 1034792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOverlap, jac->hsolver, 0); 1035792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, jac->nodal_relax_levels); 10368f87f92bSBarry Smith } 10378f87f92bSBarry Smith 10389566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL)); 1039792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 1040589dcaf0SStefano Zampini 1041589dcaf0SStefano Zampini /* options for ParaSails solvers */ 1042dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flg)); 1043589dcaf0SStefano Zampini if (flg) { 1044589dcaf0SStefano Zampini jac->symt = indx; 1045792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSym, jac->hsolver, jac->symt); 1046589dcaf0SStefano Zampini } 1047589dcaf0SStefano Zampini 1048d0609cedSBarry Smith PetscOptionsHeadEnd(); 10493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 105016d9e3a6SLisandro Dalcin } 105116d9e3a6SLisandro Dalcin 1052d71ae5a4SJacob 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) 1053d71ae5a4SJacob Faibussowitsch { 105416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 10552cf14000SStefano Zampini HYPRE_Int oits; 105616d9e3a6SLisandro Dalcin 105716d9e3a6SLisandro Dalcin PetscFunctionBegin; 10589566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 1059792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, its * jac->maxiter); 1060792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, rtol); 106116d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 10629566063dSJacob Faibussowitsch PetscCall(PCApply_HYPRE(pc, b, y)); 106316d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 1064792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGGetNumIterations, jac->hsolver, &oits); 10654d0a8057SBarry Smith *outits = oits; 10664d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 10674d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1068792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 1069792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 10703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 107116d9e3a6SLisandro Dalcin } 107216d9e3a6SLisandro Dalcin 1073d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc, PetscViewer viewer) 1074d71ae5a4SJacob Faibussowitsch { 107516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1076ace3abfcSBarry Smith PetscBool iascii; 107716d9e3a6SLisandro Dalcin 107816d9e3a6SLisandro Dalcin PetscFunctionBegin; 10799566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 108016d9e3a6SLisandro Dalcin if (iascii) { 10819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE BoomerAMG preconditioning\n")); 10829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Cycle type %s\n", HYPREBoomerAMGCycleType[jac->cycletype])); 108363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of levels %" PetscInt_FMT "\n", jac->maxlevels)); 108463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of iterations PER hypre call %" PetscInt_FMT "\n", jac->maxiter)); 10859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Convergence tolerance PER hypre call %g\n", (double)jac->tol)); 10869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for strong coupling %g\n", (double)jac->strongthreshold)); 10879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation truncation factor %g\n", (double)jac->truncfactor)); 108863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: max elements per row %" PetscInt_FMT "\n", jac->pmax)); 108948a46eb9SPierre Jolivet if (jac->interp_refine) PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n", jac->interp_refine)); 109063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of levels of aggressive coarsening %" PetscInt_FMT "\n", jac->agg_nl)); 109163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of paths for aggressive coarsening %" PetscInt_FMT "\n", jac->agg_num_paths)); 10920f1074feSSatish Balay 10939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum row sums %g\n", (double)jac->maxrowsum)); 109416d9e3a6SLisandro Dalcin 109563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps down %" PetscInt_FMT "\n", jac->gridsweeps[0])); 109663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps up %" PetscInt_FMT "\n", jac->gridsweeps[1])); 109763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps on coarse %" PetscInt_FMT "\n", jac->gridsweeps[2])); 109816d9e3a6SLisandro Dalcin 10999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax down %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[0]])); 11009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax up %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[1]])); 11019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax on coarse %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[2]])); 110216d9e3a6SLisandro Dalcin 11039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax weight (all) %g\n", (double)jac->relaxweight)); 11049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Outer relax weight (all) %g\n", (double)jac->outerrelaxweight)); 110516d9e3a6SLisandro Dalcin 110616d9e3a6SLisandro Dalcin if (jac->relaxorder) { 11079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using CF-relaxation\n")); 110816d9e3a6SLisandro Dalcin } else { 11099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using CF-relaxation\n")); 111016d9e3a6SLisandro Dalcin } 11116a251517SEike Mueller if (jac->smoothtype != -1) { 11129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth type %s\n", HYPREBoomerAMGSmoothType[jac->smoothtype])); 111363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num levels %" PetscInt_FMT "\n", jac->smoothnumlevels)); 11147e352d70SEike Mueller } else { 11159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using more complex smoothers.\n")); 11161810e44eSEike Mueller } 11171810e44eSEike Mueller if (jac->smoothtype == 3) { 111863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) levels %" PetscInt_FMT "\n", jac->eu_level)); 11199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) drop tolerance %g\n", (double)jac->eu_droptolerance)); 112063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 11216a251517SEike Mueller } 11229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Measure type %s\n", HYPREBoomerAMGMeasureType[jac->measuretype])); 11239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Coarsen type %s\n", HYPREBoomerAMGCoarsenType[jac->coarsentype])); 11249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation type %s\n", jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt")); 112548a46eb9SPierre Jolivet if (jac->nodal_coarsening) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n", jac->nodal_coarsening)); 11265272c319SBarry Smith if (jac->vec_interp_variant) { 112763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n", jac->vec_interp_variant)); 112863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n", jac->vec_interp_qmax)); 11299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n", jac->vec_interp_smooth)); 11308f87f92bSBarry Smith } 113148a46eb9SPierre Jolivet if (jac->nodal_relax) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n", jac->nodal_relax_levels)); 1132db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 11339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", jac->spgemm_type)); 11342d6c3ceeSStefano Zampini #else 11352d6c3ceeSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", "hypre")); 1136db6f9c32SMark Adams #endif 1137589dcaf0SStefano Zampini /* AIR */ 1138589dcaf0SStefano Zampini if (jac->Rtype) { 113963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using approximate ideal restriction type %" PetscInt_FMT "\n", jac->Rtype)); 11409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for R %g\n", (double)jac->Rstrongthreshold)); 11419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Filter for R %g\n", (double)jac->Rfilterthreshold)); 11429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop tolerance %g\n", (double)jac->Adroptol)); 114363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop type %" PetscInt_FMT "\n", jac->Adroptype)); 1144589dcaf0SStefano Zampini } 114516d9e3a6SLisandro Dalcin } 11463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 114716d9e3a6SLisandro Dalcin } 114816d9e3a6SLisandro Dalcin 1149d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc, PetscOptionItems *PetscOptionsObject) 1150d71ae5a4SJacob Faibussowitsch { 115116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 11524ddd07fcSJed Brown PetscInt indx; 1153ace3abfcSBarry Smith PetscBool flag; 115416d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 115516d9e3a6SLisandro Dalcin 115616d9e3a6SLisandro Dalcin PetscFunctionBegin; 1157d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ParaSails Options"); 11589566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels", "Number of number of levels", "None", jac->nlevels, &jac->nlevels, 0)); 11599566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh", "Threshold", "None", jac->threshold, &jac->threshold, &flag)); 1160792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 116116d9e3a6SLisandro Dalcin 11629566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter", "filter", "None", jac->filter, &jac->filter, &flag)); 1163792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 116416d9e3a6SLisandro Dalcin 11659566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal", "Load balance", "None", jac->loadbal, &jac->loadbal, &flag)); 1166792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 116716d9e3a6SLisandro Dalcin 11689566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging", "Print info to screen", "None", (PetscBool)jac->logging, (PetscBool *)&jac->logging, &flag)); 1169792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 117016d9e3a6SLisandro Dalcin 11719566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse", "Reuse nonzero pattern in preconditioner", "None", (PetscBool)jac->ruse, (PetscBool *)&jac->ruse, &flag)); 1172792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 117316d9e3a6SLisandro Dalcin 1174dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flag)); 117516d9e3a6SLisandro Dalcin if (flag) { 117616d9e3a6SLisandro Dalcin jac->symt = indx; 1177792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 117816d9e3a6SLisandro Dalcin } 117916d9e3a6SLisandro Dalcin 1180d0609cedSBarry Smith PetscOptionsHeadEnd(); 11813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 118216d9e3a6SLisandro Dalcin } 118316d9e3a6SLisandro Dalcin 1184d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ParaSails(PC pc, PetscViewer viewer) 1185d71ae5a4SJacob Faibussowitsch { 118616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1187ace3abfcSBarry Smith PetscBool iascii; 1188feb237baSPierre Jolivet const char *symt = 0; 118916d9e3a6SLisandro Dalcin 119016d9e3a6SLisandro Dalcin PetscFunctionBegin; 11919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 119216d9e3a6SLisandro Dalcin if (iascii) { 11939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ParaSails preconditioning\n")); 119463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " nlevels %" PetscInt_FMT "\n", jac->nlevels)); 11959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " threshold %g\n", (double)jac->threshold)); 11969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " filter %g\n", (double)jac->filter)); 11979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " load balance %g\n", (double)jac->loadbal)); 11989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " reuse nonzero structure %s\n", PetscBools[jac->ruse])); 11999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " print info to screen %s\n", PetscBools[jac->logging])); 12002fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 12012fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 12022fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 120363a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONG, "Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT, jac->symt); 12049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", symt)); 120516d9e3a6SLisandro Dalcin } 12063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 120716d9e3a6SLisandro Dalcin } 1208f1580f4eSBarry Smith 1209d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc, PetscOptionItems *PetscOptionsObject) 1210d71ae5a4SJacob Faibussowitsch { 12114cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 12124cb006feSStefano Zampini PetscInt n; 12134cb006feSStefano Zampini PetscBool flag, flag2, flag3, flag4; 12144cb006feSStefano Zampini 12154cb006feSStefano Zampini PetscFunctionBegin; 1216d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE AMS Options"); 12179566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level", "Debugging output level for AMS", "None", jac->as_print, &jac->as_print, &flag)); 1218792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 12199566063dSJacob 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)); 1220792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 12219566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type", "Cycle type for AMS multigrid", "None", jac->ams_cycle_type, &jac->ams_cycle_type, &flag)); 1222792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 12239566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_tol", "Error tolerance for AMS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1224792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 12259566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type", "Relaxation type for AMS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 12269566063dSJacob 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)); 12279566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight", "Relaxation weight for AMS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 12289566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_omega", "SSOR coefficient for AMS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 122948a46eb9SPierre 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); 12309566063dSJacob 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)); 12314cb006feSStefano Zampini n = 5; 12329566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options", "AMG options for vector Poisson", "None", jac->as_amg_alpha_opts, &n, &flag2)); 12334cb006feSStefano Zampini if (flag || flag2) { 1234792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1235863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1236863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 12379371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1238a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 12394cb006feSStefano Zampini } 12409566063dSJacob 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)); 12414cb006feSStefano Zampini n = 5; 12429566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options", "AMG options for scalar Poisson solver", "None", jac->as_amg_beta_opts, &n, &flag2)); 12434cb006feSStefano Zampini if (flag || flag2) { 1244792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1245863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1246863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 12479371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1248a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 12494cb006feSStefano Zampini } 12509566063dSJacob 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)); 125123df4f25SStefano Zampini if (flag) { /* override HYPRE's default only if the options is used */ 1252792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetProjectionFrequency, jac->hsolver, jac->ams_proj_freq); 125323df4f25SStefano Zampini } 1254d0609cedSBarry Smith PetscOptionsHeadEnd(); 12553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12564cb006feSStefano Zampini } 12574cb006feSStefano Zampini 1258d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_AMS(PC pc, PetscViewer viewer) 1259d71ae5a4SJacob Faibussowitsch { 12604cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 12614cb006feSStefano Zampini PetscBool iascii; 12624cb006feSStefano Zampini 12634cb006feSStefano Zampini PetscFunctionBegin; 12649566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 12654cb006feSStefano Zampini if (iascii) { 12669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE AMS preconditioning\n")); 126763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 126863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 126963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 127063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 127163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 127263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 127363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 12744cb006feSStefano Zampini if (jac->alpha_Poisson) { 12759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (passed in by user)\n")); 12764cb006feSStefano Zampini } else { 12779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (computed) \n")); 12784cb006feSStefano Zampini } 127963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 128063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 128163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 128263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 128363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 128463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 12854cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 12864cb006feSStefano Zampini if (jac->beta_Poisson) { 12879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (passed in by user)\n")); 12884cb006feSStefano Zampini } else { 12899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (computed) \n")); 12904cb006feSStefano Zampini } 129163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 129263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 129363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 129463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 129563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 129663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_beta_theta)); 129748a46eb9SPierre 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)); 129823df4f25SStefano Zampini } else { 12999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver not used (zero-conductivity everywhere) \n")); 13004cb006feSStefano Zampini } 13014cb006feSStefano Zampini } 13023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13034cb006feSStefano Zampini } 13044cb006feSStefano Zampini 1305d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PC pc, PetscOptionItems *PetscOptionsObject) 1306d71ae5a4SJacob Faibussowitsch { 1307863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1308863406b8SStefano Zampini PetscInt n; 1309863406b8SStefano Zampini PetscBool flag, flag2, flag3, flag4; 1310863406b8SStefano Zampini 1311863406b8SStefano Zampini PetscFunctionBegin; 1312d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ADS Options"); 13139566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level", "Debugging output level for ADS", "None", jac->as_print, &jac->as_print, &flag)); 1314792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 13159566063dSJacob 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)); 1316792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 13179566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type", "Cycle type for ADS multigrid", "None", jac->ads_cycle_type, &jac->ads_cycle_type, &flag)); 1318792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ads_cycle_type); 13199566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_tol", "Error tolerance for ADS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1320792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 13219566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type", "Relaxation type for ADS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 13229566063dSJacob 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)); 13239566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight", "Relaxation weight for ADS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 13249566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_omega", "SSOR coefficient for ADS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 132548a46eb9SPierre 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); 13269566063dSJacob 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)); 1327863406b8SStefano Zampini n = 5; 13289566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options", "AMG options for AMS solver inside ADS", "None", jac->as_amg_alpha_opts, &n, &flag2)); 13299566063dSJacob 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)); 1330863406b8SStefano Zampini if (flag || flag2 || flag3) { 1331792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMS cycle type */ 1332863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1333863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1334863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 13359371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1336a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 1337863406b8SStefano Zampini } 13389566063dSJacob 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)); 1339863406b8SStefano Zampini n = 5; 13409566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options", "AMG options for vector AMG solver inside ADS", "None", jac->as_amg_beta_opts, &n, &flag2)); 1341863406b8SStefano Zampini if (flag || flag2) { 1342792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1343863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1344863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 13459371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1346a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 1347863406b8SStefano Zampini } 1348d0609cedSBarry Smith PetscOptionsHeadEnd(); 13493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1350863406b8SStefano Zampini } 1351863406b8SStefano Zampini 1352d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ADS(PC pc, PetscViewer viewer) 1353d71ae5a4SJacob Faibussowitsch { 1354863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1355863406b8SStefano Zampini PetscBool iascii; 1356863406b8SStefano Zampini 1357863406b8SStefano Zampini PetscFunctionBegin; 13589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1359863406b8SStefano Zampini if (iascii) { 13609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ADS preconditioning\n")); 136163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 136263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ads_cycle_type)); 136363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 136463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 136563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 136663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 136763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 13689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " AMS solver using boomerAMG\n")); 136963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 137063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 137163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 137263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 137363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 137463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 137563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 13769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver using boomerAMG\n")); 137763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 137863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 137963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 138063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 138163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 138263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_beta_theta)); 1383863406b8SStefano Zampini } 13843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1385863406b8SStefano Zampini } 1386863406b8SStefano Zampini 1387d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G) 1388d71ae5a4SJacob Faibussowitsch { 13894cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 13905ac14e1cSStefano Zampini PetscBool ishypre; 13914cb006feSStefano Zampini 13924cb006feSStefano Zampini PetscFunctionBegin; 13939566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)G, MATHYPRE, &ishypre)); 13945ac14e1cSStefano Zampini if (ishypre) { 13959566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)G)); 13969566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 13975ac14e1cSStefano Zampini jac->G = G; 13985ac14e1cSStefano Zampini } else { 13999566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 14009566063dSJacob Faibussowitsch PetscCall(MatConvert(G, MATHYPRE, MAT_INITIAL_MATRIX, &jac->G)); 14015ac14e1cSStefano Zampini } 14023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14034cb006feSStefano Zampini } 14044cb006feSStefano Zampini 14054cb006feSStefano Zampini /*@ 1406f1580f4eSBarry Smith PCHYPRESetDiscreteGradient - Set discrete gradient matrix for `PCHYPRE` type of ams or ads 14074cb006feSStefano Zampini 1408c3339decSBarry Smith Collective 14094cb006feSStefano Zampini 14104cb006feSStefano Zampini Input Parameters: 14114cb006feSStefano Zampini + pc - the preconditioning context 14124cb006feSStefano Zampini - G - the discrete gradient 14134cb006feSStefano Zampini 14144cb006feSStefano Zampini Level: intermediate 14154cb006feSStefano Zampini 141695452b02SPatrick Sanan Notes: 141795452b02SPatrick Sanan G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 1418147403d9SBarry Smith 1419863406b8SStefano 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 14204cb006feSStefano Zampini 1421f1580f4eSBarry Smith Developer Note: 1422f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1423f1580f4eSBarry Smith 1424f1580f4eSBarry Smith .seealso: `PCHYPRE`, `PCHYPRESetDiscreteCurl()` 14254cb006feSStefano Zampini @*/ 1426d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 1427d71ae5a4SJacob Faibussowitsch { 14284cb006feSStefano Zampini PetscFunctionBegin; 14294cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 14304cb006feSStefano Zampini PetscValidHeaderSpecific(G, MAT_CLASSID, 2); 14314cb006feSStefano Zampini PetscCheckSameComm(pc, 1, G, 2); 1432cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteGradient_C", (PC, Mat), (pc, G)); 14333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14344cb006feSStefano Zampini } 14354cb006feSStefano Zampini 1436d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C) 1437d71ae5a4SJacob Faibussowitsch { 1438863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 14395ac14e1cSStefano Zampini PetscBool ishypre; 1440863406b8SStefano Zampini 1441863406b8SStefano Zampini PetscFunctionBegin; 14429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C, MATHYPRE, &ishypre)); 14435ac14e1cSStefano Zampini if (ishypre) { 14449566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)C)); 14459566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 14465ac14e1cSStefano Zampini jac->C = C; 14475ac14e1cSStefano Zampini } else { 14489566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 14499566063dSJacob Faibussowitsch PetscCall(MatConvert(C, MATHYPRE, MAT_INITIAL_MATRIX, &jac->C)); 14505ac14e1cSStefano Zampini } 14513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1452863406b8SStefano Zampini } 1453863406b8SStefano Zampini 1454863406b8SStefano Zampini /*@ 1455f1580f4eSBarry Smith PCHYPRESetDiscreteCurl - Set discrete curl matrx for `PCHYPRE` type of ads 1456863406b8SStefano Zampini 1457c3339decSBarry Smith Collective 1458863406b8SStefano Zampini 1459863406b8SStefano Zampini Input Parameters: 1460863406b8SStefano Zampini + pc - the preconditioning context 1461863406b8SStefano Zampini - C - the discrete curl 1462863406b8SStefano Zampini 1463863406b8SStefano Zampini Level: intermediate 1464863406b8SStefano Zampini 146595452b02SPatrick Sanan Notes: 146695452b02SPatrick Sanan C should have as many rows as the number of faces and as many columns as the number of edges in the mesh 1467147403d9SBarry Smith 1468863406b8SStefano Zampini Each row of G has as many nonzeros as the number of edges of a face, with column indexes being the global indexes of the corresponding edge: matrix entries are +1 and -1 depending on edge orientation with respect to the face orientation 1469863406b8SStefano Zampini 1470f1580f4eSBarry Smith Developer Note: 1471f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1472f1580f4eSBarry Smith 1473f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ads it should be called `PCHYPREADSSetDiscreteCurl()` 1474f1580f4eSBarry Smith 1475f1580f4eSBarry Smith .seealso: `PCHYPRE`, `PCHYPRESetDiscreteGradient()` 1476863406b8SStefano Zampini @*/ 1477d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C) 1478d71ae5a4SJacob Faibussowitsch { 1479863406b8SStefano Zampini PetscFunctionBegin; 1480863406b8SStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1481863406b8SStefano Zampini PetscValidHeaderSpecific(C, MAT_CLASSID, 2); 1482863406b8SStefano Zampini PetscCheckSameComm(pc, 1, C, 2); 1483cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteCurl_C", (PC, Mat), (pc, C)); 14843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1485863406b8SStefano Zampini } 1486863406b8SStefano Zampini 1487d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1488d71ae5a4SJacob Faibussowitsch { 14896bf688a0SCe Qin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 14906bf688a0SCe Qin PetscBool ishypre; 14916bf688a0SCe Qin PetscInt i; 14926bf688a0SCe Qin PetscFunctionBegin; 14936bf688a0SCe Qin 14949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 14959566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 14966bf688a0SCe Qin for (i = 0; i < 3; ++i) { 14979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[i])); 14989566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[i])); 14996bf688a0SCe Qin } 15006bf688a0SCe Qin 15016bf688a0SCe Qin jac->dim = dim; 15026bf688a0SCe Qin if (RT_PiFull) { 15039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_PiFull, MATHYPRE, &ishypre)); 15046bf688a0SCe Qin if (ishypre) { 15059566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_PiFull)); 15066bf688a0SCe Qin jac->RT_PiFull = RT_PiFull; 15076bf688a0SCe Qin } else { 15089566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_PiFull)); 15096bf688a0SCe Qin } 15106bf688a0SCe Qin } 15116bf688a0SCe Qin if (RT_Pi) { 15126bf688a0SCe Qin for (i = 0; i < dim; ++i) { 15136bf688a0SCe Qin if (RT_Pi[i]) { 15149566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_Pi[i], MATHYPRE, &ishypre)); 15156bf688a0SCe Qin if (ishypre) { 15169566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_Pi[i])); 15176bf688a0SCe Qin jac->RT_Pi[i] = RT_Pi[i]; 15186bf688a0SCe Qin } else { 15199566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_Pi[i])); 15206bf688a0SCe Qin } 15216bf688a0SCe Qin } 15226bf688a0SCe Qin } 15236bf688a0SCe Qin } 15246bf688a0SCe Qin if (ND_PiFull) { 15259566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_PiFull, MATHYPRE, &ishypre)); 15266bf688a0SCe Qin if (ishypre) { 15279566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_PiFull)); 15286bf688a0SCe Qin jac->ND_PiFull = ND_PiFull; 15296bf688a0SCe Qin } else { 15309566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_PiFull)); 15316bf688a0SCe Qin } 15326bf688a0SCe Qin } 15336bf688a0SCe Qin if (ND_Pi) { 15346bf688a0SCe Qin for (i = 0; i < dim; ++i) { 15356bf688a0SCe Qin if (ND_Pi[i]) { 15369566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_Pi[i], MATHYPRE, &ishypre)); 15376bf688a0SCe Qin if (ishypre) { 15389566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_Pi[i])); 15396bf688a0SCe Qin jac->ND_Pi[i] = ND_Pi[i]; 15406bf688a0SCe Qin } else { 15419566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_Pi[i])); 15426bf688a0SCe Qin } 15436bf688a0SCe Qin } 15446bf688a0SCe Qin } 15456bf688a0SCe Qin } 15466bf688a0SCe Qin 15473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15486bf688a0SCe Qin } 15496bf688a0SCe Qin 15506bf688a0SCe Qin /*@ 1551f1580f4eSBarry Smith PCHYPRESetInterpolations - Set interpolation matrices for `PCHYPRE` type of ams or ads 15526bf688a0SCe Qin 1553c3339decSBarry Smith Collective 15546bf688a0SCe Qin 15556bf688a0SCe Qin Input Parameters: 15566bf688a0SCe Qin + pc - the preconditioning context 15572fe279fdSBarry Smith . dim - the dimension of the problem, only used in AMS 15582fe279fdSBarry Smith . RT_PiFull - Raviart-Thomas interpolation matrix 15592fe279fdSBarry Smith . RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix 15602fe279fdSBarry Smith . ND_PiFull - Nedelec interpolation matrix 15616bf688a0SCe Qin - ND_Pi - x/y/z component of Nedelec interpolation matrix 15626bf688a0SCe Qin 1563f1580f4eSBarry Smith Level: intermediate 1564f1580f4eSBarry Smith 156595452b02SPatrick Sanan Notes: 156695452b02SPatrick Sanan For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL. 1567147403d9SBarry Smith 15686bf688a0SCe Qin For ADS, both type of interpolation matrices are needed. 1569147403d9SBarry Smith 1570f1580f4eSBarry Smith Developer Note: 1571f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 15726bf688a0SCe Qin 1573f1580f4eSBarry Smith .seealso: `PCHYPRE` 15746bf688a0SCe Qin @*/ 1575d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1576d71ae5a4SJacob Faibussowitsch { 15776bf688a0SCe Qin PetscInt i; 15786bf688a0SCe Qin 15796bf688a0SCe Qin PetscFunctionBegin; 15806bf688a0SCe Qin PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 15816bf688a0SCe Qin if (RT_PiFull) { 15826bf688a0SCe Qin PetscValidHeaderSpecific(RT_PiFull, MAT_CLASSID, 3); 15836bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_PiFull, 3); 15846bf688a0SCe Qin } 15856bf688a0SCe Qin if (RT_Pi) { 15866bf688a0SCe Qin PetscValidPointer(RT_Pi, 4); 15876bf688a0SCe Qin for (i = 0; i < dim; ++i) { 15886bf688a0SCe Qin if (RT_Pi[i]) { 15896bf688a0SCe Qin PetscValidHeaderSpecific(RT_Pi[i], MAT_CLASSID, 4); 15906bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_Pi[i], 4); 15916bf688a0SCe Qin } 15926bf688a0SCe Qin } 15936bf688a0SCe Qin } 15946bf688a0SCe Qin if (ND_PiFull) { 15956bf688a0SCe Qin PetscValidHeaderSpecific(ND_PiFull, MAT_CLASSID, 5); 15966bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_PiFull, 5); 15976bf688a0SCe Qin } 15986bf688a0SCe Qin if (ND_Pi) { 15996bf688a0SCe Qin PetscValidPointer(ND_Pi, 6); 16006bf688a0SCe Qin for (i = 0; i < dim; ++i) { 16016bf688a0SCe Qin if (ND_Pi[i]) { 16026bf688a0SCe Qin PetscValidHeaderSpecific(ND_Pi[i], MAT_CLASSID, 6); 16036bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_Pi[i], 6); 16046bf688a0SCe Qin } 16056bf688a0SCe Qin } 16066bf688a0SCe Qin } 1607cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetInterpolations_C", (PC, PetscInt, Mat, Mat[], Mat, Mat[]), (pc, dim, RT_PiFull, RT_Pi, ND_PiFull, ND_Pi)); 16083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16096bf688a0SCe Qin } 16106bf688a0SCe Qin 1611d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha) 1612d71ae5a4SJacob Faibussowitsch { 16134cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 16145ac14e1cSStefano Zampini PetscBool ishypre; 16154cb006feSStefano Zampini 16164cb006feSStefano Zampini PetscFunctionBegin; 16179566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 16185ac14e1cSStefano Zampini if (ishypre) { 16195ac14e1cSStefano Zampini if (isalpha) { 16209566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 16219566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 16225ac14e1cSStefano Zampini jac->alpha_Poisson = A; 16235ac14e1cSStefano Zampini } else { 16245ac14e1cSStefano Zampini if (A) { 16259566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 16265ac14e1cSStefano Zampini } else { 16275ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 16285ac14e1cSStefano Zampini } 16299566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16305ac14e1cSStefano Zampini jac->beta_Poisson = A; 16315ac14e1cSStefano Zampini } 16325ac14e1cSStefano Zampini } else { 16335ac14e1cSStefano Zampini if (isalpha) { 16349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 16359566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->alpha_Poisson)); 16365ac14e1cSStefano Zampini } else { 16375ac14e1cSStefano Zampini if (A) { 16389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16399566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->beta_Poisson)); 16405ac14e1cSStefano Zampini } else { 16419566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16425ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 16435ac14e1cSStefano Zampini } 16445ac14e1cSStefano Zampini } 16455ac14e1cSStefano Zampini } 16463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16474cb006feSStefano Zampini } 16484cb006feSStefano Zampini 16494cb006feSStefano Zampini /*@ 1650f1580f4eSBarry Smith PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix for `PCHYPRE` of type ams 16514cb006feSStefano Zampini 1652c3339decSBarry Smith Collective 16534cb006feSStefano Zampini 16544cb006feSStefano Zampini Input Parameters: 16554cb006feSStefano Zampini + pc - the preconditioning context 16564cb006feSStefano Zampini - A - the matrix 16574cb006feSStefano Zampini 16584cb006feSStefano Zampini Level: intermediate 16594cb006feSStefano Zampini 1660f1580f4eSBarry Smith Note: 166195452b02SPatrick Sanan A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 16624cb006feSStefano Zampini 1663f1580f4eSBarry Smith Developer Note: 1664f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1665f1580f4eSBarry Smith 1666f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetAlphaPoissonMatrix()` 1667f1580f4eSBarry Smith 1668f1580f4eSBarry Smith .seealso: `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()` 16694cb006feSStefano Zampini @*/ 1670d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 1671d71ae5a4SJacob Faibussowitsch { 16724cb006feSStefano Zampini PetscFunctionBegin; 16734cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 16744cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 16754cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 1676cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_TRUE)); 16773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16784cb006feSStefano Zampini } 16794cb006feSStefano Zampini 16804cb006feSStefano Zampini /*@ 1681f1580f4eSBarry Smith PCHYPRESetBetaPoissonMatrix - Set Poisson matrix for `PCHYPRE` of type ams 16824cb006feSStefano Zampini 1683c3339decSBarry Smith Collective 16844cb006feSStefano Zampini 16854cb006feSStefano Zampini Input Parameters: 16864cb006feSStefano Zampini + pc - the preconditioning context 1687f1580f4eSBarry Smith - A - the matrix, or NULL to turn it off 16884cb006feSStefano Zampini 16894cb006feSStefano Zampini Level: intermediate 16904cb006feSStefano Zampini 1691f1580f4eSBarry Smith Note: 169295452b02SPatrick Sanan A should be obtained by discretizing the Poisson problem with linear finite elements. 16934cb006feSStefano Zampini 1694f1580f4eSBarry Smith Developer Note: 1695f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1696f1580f4eSBarry Smith 1697f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSPCHYPRESetBetaPoissonMatrix()` 1698f1580f4eSBarry Smith 1699f1580f4eSBarry Smith .seealso: `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 17004cb006feSStefano Zampini @*/ 1701d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 1702d71ae5a4SJacob Faibussowitsch { 17034cb006feSStefano Zampini PetscFunctionBegin; 17044cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 17054cb006feSStefano Zampini if (A) { 17064cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 17074cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 17084cb006feSStefano Zampini } 1709cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_FALSE)); 17103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17114cb006feSStefano Zampini } 17124cb006feSStefano Zampini 1713d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc, Vec ozz, Vec zoz, Vec zzo) 1714d71ae5a4SJacob Faibussowitsch { 17154cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 17164cb006feSStefano Zampini 17174cb006feSStefano Zampini PetscFunctionBegin; 17184cb006feSStefano Zampini /* throw away any vector if already set */ 17199566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 17209566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 17219566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 17229566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(ozz->map, &jac->constants[0])); 17239566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(ozz, jac->constants[0])); 17249566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zoz->map, &jac->constants[1])); 17259566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zoz, jac->constants[1])); 17265ac14e1cSStefano Zampini jac->dim = 2; 17274cb006feSStefano Zampini if (zzo) { 17289566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zzo->map, &jac->constants[2])); 17299566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zzo, jac->constants[2])); 17305ac14e1cSStefano Zampini jac->dim++; 17314cb006feSStefano Zampini } 17323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17334cb006feSStefano Zampini } 17344cb006feSStefano Zampini 17354cb006feSStefano Zampini /*@ 1736f1580f4eSBarry Smith PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis for `PCHYPRE` of type ams 17374cb006feSStefano Zampini 1738c3339decSBarry Smith Collective 17394cb006feSStefano Zampini 17404cb006feSStefano Zampini Input Parameters: 17414cb006feSStefano Zampini + pc - the preconditioning context 17422fe279fdSBarry Smith . ozz - vector representing (1,0,0) (or (1,0) in 2D) 17432fe279fdSBarry Smith . zoz - vector representing (0,1,0) (or (0,1) in 2D) 17444cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 17454cb006feSStefano Zampini 17464cb006feSStefano Zampini Level: intermediate 17474cb006feSStefano Zampini 1748f1580f4eSBarry Smith Developer Note: 1749f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetEdgeConstantVectors()` 1750f1580f4eSBarry Smith 1751f1580f4eSBarry Smith .seealso: `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 17524cb006feSStefano Zampini @*/ 1753d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 1754d71ae5a4SJacob Faibussowitsch { 17554cb006feSStefano Zampini PetscFunctionBegin; 17564cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 17574cb006feSStefano Zampini PetscValidHeaderSpecific(ozz, VEC_CLASSID, 2); 17584cb006feSStefano Zampini PetscValidHeaderSpecific(zoz, VEC_CLASSID, 3); 17594cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo, VEC_CLASSID, 4); 17604cb006feSStefano Zampini PetscCheckSameComm(pc, 1, ozz, 2); 17614cb006feSStefano Zampini PetscCheckSameComm(pc, 1, zoz, 3); 17624cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc, 1, zzo, 4); 1763cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetEdgeConstantVectors_C", (PC, Vec, Vec, Vec), (pc, ozz, zoz, zzo)); 17643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17654cb006feSStefano Zampini } 17664cb006feSStefano Zampini 1767d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREAMSSetInteriorNodes_HYPRE(PC pc, Vec interior) 1768d71ae5a4SJacob Faibussowitsch { 1769be14dc20SKerry Key PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1770be14dc20SKerry Key 1771be14dc20SKerry Key PetscFunctionBegin; 1772be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 1773be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCreate(interior->map, &jac->interior)); 1774be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCopy(interior, jac->interior)); 1775be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_TRUE; 17763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1777be14dc20SKerry Key } 1778be14dc20SKerry Key 1779be14dc20SKerry Key /*@ 1780f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes - Set the list of interior nodes to a zero-conductivity region for `PCHYPRE` of type ams 1781be14dc20SKerry Key 1782c3339decSBarry Smith Collective 1783be14dc20SKerry Key 1784be14dc20SKerry Key Input Parameters: 1785be14dc20SKerry Key + pc - the preconditioning context 1786be14dc20SKerry Key - interior - vector. node is interior if its entry in the array is 1.0. 1787be14dc20SKerry Key 1788be14dc20SKerry Key Level: intermediate 1789be14dc20SKerry Key 1790be14dc20SKerry Key Note: 1791f1580f4eSBarry Smith This calls `HYPRE_AMSSetInteriorNodes()` 1792f1580f4eSBarry Smith 1793f1580f4eSBarry Smith Developer Note: 1794f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetInteriorNodes()` 1795f1580f4eSBarry Smith 1796f1580f4eSBarry Smith .seealso: `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 1797be14dc20SKerry Key @*/ 1798d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREAMSSetInteriorNodes(PC pc, Vec interior) 1799d71ae5a4SJacob Faibussowitsch { 1800be14dc20SKerry Key PetscFunctionBegin; 1801be14dc20SKerry Key PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1802be14dc20SKerry Key PetscValidHeaderSpecific(interior, VEC_CLASSID, 2); 1803be14dc20SKerry Key PetscCheckSameComm(pc, 1, interior, 2); 1804be14dc20SKerry Key PetscTryMethod(pc, "PCHYPREAMSSetInteriorNodes_C", (PC, Vec), (pc, interior)); 18053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1806be14dc20SKerry Key } 1807be14dc20SKerry Key 1808d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 1809d71ae5a4SJacob Faibussowitsch { 18104cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 18114cb006feSStefano Zampini Vec tv; 18124cb006feSStefano Zampini PetscInt i; 18134cb006feSStefano Zampini 18144cb006feSStefano Zampini PetscFunctionBegin; 18154cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 18169566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 18179566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 18189566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 18195ac14e1cSStefano Zampini jac->dim = dim; 18205ac14e1cSStefano Zampini 18214cb006feSStefano Zampini /* compute IJ vector for coordinates */ 18229566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)pc), &tv)); 18239566063dSJacob Faibussowitsch PetscCall(VecSetType(tv, VECSTANDARD)); 18249566063dSJacob Faibussowitsch PetscCall(VecSetSizes(tv, nloc, PETSC_DECIDE)); 18254cb006feSStefano Zampini for (i = 0; i < dim; i++) { 18264cb006feSStefano Zampini PetscScalar *array; 18274cb006feSStefano Zampini PetscInt j; 18284cb006feSStefano Zampini 18299566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(tv->map, &jac->coords[i])); 18309566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(tv, &array)); 18316ea7df73SStefano Zampini for (j = 0; j < nloc; j++) array[j] = coords[j * dim + i]; 18329566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(tv, &array)); 18339566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(tv, jac->coords[i])); 18344cb006feSStefano Zampini } 18359566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tv)); 18363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18374cb006feSStefano Zampini } 18384cb006feSStefano Zampini 1839d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREGetType_HYPRE(PC pc, const char *name[]) 1840d71ae5a4SJacob Faibussowitsch { 184116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 184216d9e3a6SLisandro Dalcin 184316d9e3a6SLisandro Dalcin PetscFunctionBegin; 184416d9e3a6SLisandro Dalcin *name = jac->hypre_type; 18453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 184616d9e3a6SLisandro Dalcin } 184716d9e3a6SLisandro Dalcin 1848d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetType_HYPRE(PC pc, const char name[]) 1849d71ae5a4SJacob Faibussowitsch { 185016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1851ace3abfcSBarry Smith PetscBool flag; 185216d9e3a6SLisandro Dalcin 185316d9e3a6SLisandro Dalcin PetscFunctionBegin; 185416d9e3a6SLisandro Dalcin if (jac->hypre_type) { 18559566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, name, &flag)); 18565f80ce2aSJacob Faibussowitsch PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "Cannot reset the HYPRE preconditioner type once it has been set"); 18573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 185816d9e3a6SLisandro Dalcin } else { 18599566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->hypre_type)); 186016d9e3a6SLisandro Dalcin } 186116d9e3a6SLisandro Dalcin 186216d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 186316d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 186416d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 186516d9e3a6SLisandro Dalcin 18669566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("pilut", jac->hypre_type, &flag)); 186716d9e3a6SLisandro Dalcin if (flag) { 18689566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 1869792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRPilutCreate, jac->comm_hypre, &jac->hsolver); 187016d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 187116d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 187216d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 187316d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 187416d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 187516d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 18763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 187716d9e3a6SLisandro Dalcin } 18789566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("euclid", jac->hypre_type, &flag)); 1879db966c6cSHong Zhang if (flag) { 18804e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 18817de69702SBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Hypre Euclid does not support 64-bit indices"); 18828bf83915SBarry Smith #endif 18839566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 1884792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidCreate, jac->comm_hypre, &jac->hsolver); 1885db966c6cSHong Zhang pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 1886db966c6cSHong Zhang pc->ops->view = PCView_HYPRE_Euclid; 1887db966c6cSHong Zhang jac->destroy = HYPRE_EuclidDestroy; 1888db966c6cSHong Zhang jac->setup = HYPRE_EuclidSetup; 1889db966c6cSHong Zhang jac->solve = HYPRE_EuclidSolve; 1890db966c6cSHong Zhang jac->factorrowsize = PETSC_DEFAULT; 1891db966c6cSHong Zhang jac->eu_level = PETSC_DEFAULT; /* default */ 18923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1893db966c6cSHong Zhang } 18949566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("parasails", jac->hypre_type, &flag)); 189516d9e3a6SLisandro Dalcin if (flag) { 18969566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 1897792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsCreate, jac->comm_hypre, &jac->hsolver); 189816d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 189916d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 190016d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 190116d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 190216d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 190316d9e3a6SLisandro Dalcin /* initialize */ 190416d9e3a6SLisandro Dalcin jac->nlevels = 1; 19058966356dSPierre Jolivet jac->threshold = .1; 190616d9e3a6SLisandro Dalcin jac->filter = .1; 190716d9e3a6SLisandro Dalcin jac->loadbal = 0; 19082fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int)PETSC_TRUE; 19092fa5cd67SKarl Rupp else jac->logging = (int)PETSC_FALSE; 19102fa5cd67SKarl Rupp 191116d9e3a6SLisandro Dalcin jac->ruse = (int)PETSC_FALSE; 191216d9e3a6SLisandro Dalcin jac->symt = 0; 1913792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 1914792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 1915792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 1916792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 1917792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 1918792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 19193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 192016d9e3a6SLisandro Dalcin } 19219566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("boomeramg", jac->hypre_type, &flag)); 192216d9e3a6SLisandro Dalcin if (flag) { 1923792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGCreate, &jac->hsolver); 192416d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 192516d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 192616d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 192716d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 192885245615SPierre Jolivet pc->ops->matapply = PCMatApply_HYPRE_BoomerAMG; 19299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", PCGetInterpolations_BoomerAMG)); 19309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", PCGetCoarseOperators_BoomerAMG)); 193116d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 193216d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 193316d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 193416d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 193516d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 193616d9e3a6SLisandro Dalcin jac->cycletype = 1; 193716d9e3a6SLisandro Dalcin jac->maxlevels = 25; 193816d9e3a6SLisandro Dalcin jac->maxiter = 1; 19398f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 194016d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 194116d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 194216d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 194316d9e3a6SLisandro Dalcin jac->coarsentype = 6; 194416d9e3a6SLisandro Dalcin jac->measuretype = 0; 19450f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 19466a251517SEike Mueller jac->smoothtype = -1; /* Not set by default */ 1947b9eb5777SEike Mueller jac->smoothnumlevels = 25; 19481810e44eSEike Mueller jac->eu_level = 0; 19491810e44eSEike Mueller jac->eu_droptolerance = 0; 19501810e44eSEike Mueller jac->eu_bj = 0; 1951589dcaf0SStefano Zampini jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */ 19520f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 195316d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 195416d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 195516d9e3a6SLisandro Dalcin jac->relaxorder = 1; 19560f1074feSSatish Balay jac->interptype = 0; 1957589dcaf0SStefano Zampini jac->Rtype = 0; 1958589dcaf0SStefano Zampini jac->Rstrongthreshold = 0.25; 1959589dcaf0SStefano Zampini jac->Rfilterthreshold = 0.0; 1960589dcaf0SStefano Zampini jac->Adroptype = -1; 1961589dcaf0SStefano Zampini jac->Adroptol = 0.0; 19620f1074feSSatish Balay jac->agg_nl = 0; 19636ea7df73SStefano Zampini jac->agg_interptype = 4; 19640f1074feSSatish Balay jac->pmax = 0; 19650f1074feSSatish Balay jac->truncfactor = 0.0; 19660f1074feSSatish Balay jac->agg_num_paths = 1; 1967589dcaf0SStefano Zampini jac->maxc = 9; 1968589dcaf0SStefano Zampini jac->minc = 1; 196922e51d31SStefano Zampini jac->nodal_coarsening = 0; 197022e51d31SStefano Zampini jac->nodal_coarsening_diag = 0; 197122e51d31SStefano Zampini jac->vec_interp_variant = 0; 197222e51d31SStefano Zampini jac->vec_interp_qmax = 0; 197322e51d31SStefano Zampini jac->vec_interp_smooth = PETSC_FALSE; 197422e51d31SStefano Zampini jac->interp_refine = 0; 19758f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 19768f87f92bSBarry Smith jac->nodal_relax_levels = 1; 19776ea7df73SStefano Zampini jac->rap2 = 0; 19786ea7df73SStefano Zampini 19796ea7df73SStefano Zampini /* GPU defaults 19806ea7df73SStefano Zampini from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options 19816ea7df73SStefano Zampini and /src/parcsr_ls/par_amg.c */ 19826ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 19836ea7df73SStefano Zampini jac->keeptranspose = PETSC_TRUE; 19846ea7df73SStefano Zampini jac->mod_rap2 = 1; 19856ea7df73SStefano Zampini jac->coarsentype = 8; 19866ea7df73SStefano Zampini jac->relaxorder = 0; 19876ea7df73SStefano Zampini jac->interptype = 6; 19886ea7df73SStefano Zampini jac->relaxtype[0] = 18; 19896ea7df73SStefano Zampini jac->relaxtype[1] = 18; 19906ea7df73SStefano Zampini jac->agg_interptype = 7; 19916ea7df73SStefano Zampini #else 19926ea7df73SStefano Zampini jac->keeptranspose = PETSC_FALSE; 19936ea7df73SStefano Zampini jac->mod_rap2 = 0; 19946ea7df73SStefano Zampini #endif 1995792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 1996792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 1997792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 1998792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 1999792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 2000792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 2001792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 2002792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 2003792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 2004792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 2005792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 2006792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 2007792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggInterpType, jac->hsolver, jac->agg_interptype); 2008792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 2009792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 2010792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, jac->relaxtype[0]); /* defaults coarse to 9 */ 2011792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps, jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */ 2012792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 2013792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 20146ea7df73SStefano Zampini /* GPU */ 20156ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 2016792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 2017792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRAP2, jac->hsolver, jac->rap2); 2018792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetModuleRAP2, jac->hsolver, jac->mod_rap2); 20196ea7df73SStefano Zampini #endif 20206ea7df73SStefano Zampini 2021589dcaf0SStefano Zampini /* AIR */ 20226ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 2023792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 2024792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 2025792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 2026792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 2027792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 20286ea7df73SStefano Zampini #endif 20293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 203016d9e3a6SLisandro Dalcin } 20319566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ams", jac->hypre_type, &flag)); 20324cb006feSStefano Zampini if (flag) { 20333ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_AMSCreate, &jac->hsolver); 20344cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 20354cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 20364cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 20374cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 20384cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 20394cb006feSStefano Zampini jac->coords[0] = NULL; 20404cb006feSStefano Zampini jac->coords[1] = NULL; 20414cb006feSStefano Zampini jac->coords[2] = NULL; 2042be14dc20SKerry Key jac->interior = NULL; 20434cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 2044863406b8SStefano Zampini jac->as_print = 0; 2045863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2046863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 20474cb006feSStefano Zampini jac->ams_cycle_type = 13; 20484cb006feSStefano Zampini /* Smoothing options */ 2049863406b8SStefano Zampini jac->as_relax_type = 2; 2050863406b8SStefano Zampini jac->as_relax_times = 1; 2051863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2052863406b8SStefano Zampini jac->as_omega = 1.0; 20534cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2054863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2055863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 20560bdd8552SBarry Smith jac->as_amg_alpha_opts[2] = 6; 2057863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2058863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2059863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 20604cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2061863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2062863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 20630bdd8552SBarry Smith jac->as_amg_beta_opts[2] = 6; 2064863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2065863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2066863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2067792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 2068792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 2069792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2070792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 20719371c9d4SSatish Balay PetscCallExternal(HYPRE_AMSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2072792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2073863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2074863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 20759371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2076a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2077792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2078863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2079863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 20809371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2081a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 208223df4f25SStefano Zampini /* Zero conductivity */ 208323df4f25SStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 208423df4f25SStefano Zampini jac->ams_beta_is_zero_part = PETSC_FALSE; 20853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20864cb006feSStefano Zampini } 20879566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ads", jac->hypre_type, &flag)); 2088863406b8SStefano Zampini if (flag) { 20893ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_ADSCreate, &jac->hsolver); 2090863406b8SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ADS; 2091863406b8SStefano Zampini pc->ops->view = PCView_HYPRE_ADS; 2092863406b8SStefano Zampini jac->destroy = HYPRE_ADSDestroy; 2093863406b8SStefano Zampini jac->setup = HYPRE_ADSSetup; 2094863406b8SStefano Zampini jac->solve = HYPRE_ADSSolve; 2095863406b8SStefano Zampini jac->coords[0] = NULL; 2096863406b8SStefano Zampini jac->coords[1] = NULL; 2097863406b8SStefano Zampini jac->coords[2] = NULL; 2098863406b8SStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */ 2099863406b8SStefano Zampini jac->as_print = 0; 2100863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2101863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 2102863406b8SStefano Zampini jac->ads_cycle_type = 13; 2103863406b8SStefano Zampini /* Smoothing options */ 2104863406b8SStefano Zampini jac->as_relax_type = 2; 2105863406b8SStefano Zampini jac->as_relax_times = 1; 2106863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2107863406b8SStefano Zampini jac->as_omega = 1.0; 2108863406b8SStefano Zampini /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2109863406b8SStefano Zampini jac->ams_cycle_type = 14; 2110863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2111863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 2112863406b8SStefano Zampini jac->as_amg_alpha_opts[2] = 6; 2113863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2114863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2115863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 2116863406b8SStefano Zampini /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2117863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2118863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 2119863406b8SStefano Zampini jac->as_amg_beta_opts[2] = 6; 2120863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2121863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2122863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2123792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 2124792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 2125792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2126792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 21279371c9d4SSatish Balay PetscCallExternal(HYPRE_ADSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2128792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMG coarsen type */ 2129863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2130863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2131863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 21329371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2133a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2134792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2135863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2136863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 21379371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2138a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 21393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2140863406b8SStefano Zampini } 21419566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 21422fa5cd67SKarl Rupp 21430298fd71SBarry Smith jac->hypre_type = NULL; 214498921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams", name); 214516d9e3a6SLisandro Dalcin } 214616d9e3a6SLisandro Dalcin 214716d9e3a6SLisandro Dalcin /* 214816d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 214916d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 215016d9e3a6SLisandro Dalcin */ 2151d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetFromOptions_HYPRE(PC pc, PetscOptionItems *PetscOptionsObject) 2152d71ae5a4SJacob Faibussowitsch { 21534ddd07fcSJed Brown PetscInt indx; 2154db966c6cSHong Zhang const char *type[] = {"euclid", "pilut", "parasails", "boomeramg", "ams", "ads"}; 2155ace3abfcSBarry Smith PetscBool flg; 215616d9e3a6SLisandro Dalcin 215716d9e3a6SLisandro Dalcin PetscFunctionBegin; 2158d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE preconditioner options"); 2159dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_type", "HYPRE preconditioner type", "PCHYPRESetType", type, PETSC_STATIC_ARRAY_LENGTH(type), "boomeramg", &indx, &flg)); 216016d9e3a6SLisandro Dalcin if (flg) { 21619566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc, type[indx])); 216202a17cd4SBarry Smith } else { 21639566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc, "boomeramg")); 216416d9e3a6SLisandro Dalcin } 2165dbbe0bcdSBarry Smith PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject); 2166d0609cedSBarry Smith PetscOptionsHeadEnd(); 21673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 216816d9e3a6SLisandro Dalcin } 216916d9e3a6SLisandro Dalcin 217016d9e3a6SLisandro Dalcin /*@C 217116d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 217216d9e3a6SLisandro Dalcin 217316d9e3a6SLisandro Dalcin Input Parameters: 217416d9e3a6SLisandro Dalcin + pc - the preconditioner context 2175db966c6cSHong Zhang - name - either euclid, pilut, parasails, boomeramg, ams, ads 217616d9e3a6SLisandro Dalcin 2177f1580f4eSBarry Smith Options Database Key: 2178db966c6cSHong Zhang -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 217916d9e3a6SLisandro Dalcin 218016d9e3a6SLisandro Dalcin Level: intermediate 218116d9e3a6SLisandro Dalcin 2182f1580f4eSBarry Smith .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRE` 218316d9e3a6SLisandro Dalcin @*/ 2184d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetType(PC pc, const char name[]) 2185d71ae5a4SJacob Faibussowitsch { 218616d9e3a6SLisandro Dalcin PetscFunctionBegin; 21870700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 218816d9e3a6SLisandro Dalcin PetscValidCharPointer(name, 2); 2189cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetType_C", (PC, const char[]), (pc, name)); 21903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 219116d9e3a6SLisandro Dalcin } 219216d9e3a6SLisandro Dalcin 219316d9e3a6SLisandro Dalcin /*@C 219416d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 219516d9e3a6SLisandro Dalcin 219616d9e3a6SLisandro Dalcin Input Parameter: 219716d9e3a6SLisandro Dalcin . pc - the preconditioner context 219816d9e3a6SLisandro Dalcin 219916d9e3a6SLisandro Dalcin Output Parameter: 2200db966c6cSHong Zhang . name - either euclid, pilut, parasails, boomeramg, ams, ads 220116d9e3a6SLisandro Dalcin 220216d9e3a6SLisandro Dalcin Level: intermediate 220316d9e3a6SLisandro Dalcin 2204f1580f4eSBarry Smith .seealso: `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`, `PCHYPRE` 220516d9e3a6SLisandro Dalcin @*/ 2206d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREGetType(PC pc, const char *name[]) 2207d71ae5a4SJacob Faibussowitsch { 220816d9e3a6SLisandro Dalcin PetscFunctionBegin; 22090700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 221016d9e3a6SLisandro Dalcin PetscValidPointer(name, 2); 2211cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPREGetType_C", (PC, const char *[]), (pc, name)); 22123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 221316d9e3a6SLisandro Dalcin } 221416d9e3a6SLisandro Dalcin 2215db6f9c32SMark Adams /*@C 2216f1580f4eSBarry Smith PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use on GPUs 2217db6f9c32SMark Adams 2218c3339decSBarry Smith Logically Collective 2219db6f9c32SMark Adams 2220db6f9c32SMark Adams Input Parameters: 2221db6f9c32SMark Adams + pc - the hypre context 2222db6f9c32SMark Adams - type - one of 'cusparse', 'hypre' 2223db6f9c32SMark Adams 2224db6f9c32SMark Adams Options Database Key: 222567b8a455SSatish Balay . -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre 2226db6f9c32SMark Adams 2227db6f9c32SMark Adams Level: intermediate 2228db6f9c32SMark Adams 2229f1580f4eSBarry Smith Developer Note: 2230f1580f4eSBarry Smith How the name starts with `PCMG`, should it not be `PCHYPREBoomerAMG`? 2231db6f9c32SMark Adams 2232f1580f4eSBarry Smith .seealso: `PCHYPRE`, `PCMGGalerkinGetMatProductAlgorithm()` 2233db6f9c32SMark Adams @*/ 2234d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc, const char name[]) 2235d71ae5a4SJacob Faibussowitsch { 2236db6f9c32SMark Adams PetscFunctionBegin; 2237db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2238cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinSetMatProductAlgorithm_C", (PC, const char[]), (pc, name)); 22393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2240db6f9c32SMark Adams } 2241db6f9c32SMark Adams 2242db6f9c32SMark Adams /*@C 2243f1580f4eSBarry Smith PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre to use on GPUs 2244db6f9c32SMark Adams 2245db6f9c32SMark Adams Not Collective 2246db6f9c32SMark Adams 2247db6f9c32SMark Adams Input Parameter: 2248db6f9c32SMark Adams . pc - the multigrid context 2249db6f9c32SMark Adams 2250db6f9c32SMark Adams Output Parameter: 2251db6f9c32SMark Adams . name - one of 'cusparse', 'hypre' 2252db6f9c32SMark Adams 2253db6f9c32SMark Adams Level: intermediate 2254db6f9c32SMark Adams 2255f1580f4eSBarry Smith .seealso: `PCHYPRE`, ``PCMGGalerkinSetMatProductAlgorithm()` 2256db6f9c32SMark Adams @*/ 2257d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc, const char *name[]) 2258d71ae5a4SJacob Faibussowitsch { 2259db6f9c32SMark Adams PetscFunctionBegin; 2260db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2261cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinGetMatProductAlgorithm_C", (PC, const char *[]), (pc, name)); 22623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2263db6f9c32SMark Adams } 2264db6f9c32SMark Adams 226516d9e3a6SLisandro Dalcin /*MC 2266f1580f4eSBarry Smith PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre as PETSc `PC` 226716d9e3a6SLisandro Dalcin 226816d9e3a6SLisandro Dalcin Options Database Keys: 2269db966c6cSHong Zhang + -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 2270f1580f4eSBarry Smith . -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see `HYPRE_BOOMERAMGSetNodal()`) 2271f1580f4eSBarry Smith . -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see `HYPRE_BoomerAMGSetInterpVecVariant()`) 2272ead8c081SBarry Smith - Many others, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX preconditioner 227316d9e3a6SLisandro Dalcin 227416d9e3a6SLisandro Dalcin Level: intermediate 227516d9e3a6SLisandro Dalcin 227695452b02SPatrick Sanan Notes: 2277f1580f4eSBarry Smith Apart from pc_hypre_type (for which there is `PCHYPRESetType()`), 227816d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 227949567fc5SPierre Jolivet or with `PetscOptionsSetValue()`, there are no functions to set them) 228016d9e3a6SLisandro Dalcin 2281c231f9e3SBarryFSmith The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations 22820f1074feSSatish Balay (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if 22830f1074feSSatish Balay -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner 2284c231f9e3SBarryFSmith (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of 22858f87f92bSBarry Smith iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations 22860f1074feSSatish Balay and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10 22870f1074feSSatish Balay then AT MOST twenty V-cycles of boomeramg will be called. 228816d9e3a6SLisandro Dalcin 22890f1074feSSatish Balay Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation 22900f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 22910f1074feSSatish Balay Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi. 229216d9e3a6SLisandro Dalcin If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly 229316d9e3a6SLisandro Dalcin and use -ksp_max_it to control the number of V-cycles. 229416d9e3a6SLisandro Dalcin (see the PETSc FAQ.html at the PETSc website under the Documentation tab). 229516d9e3a6SLisandro Dalcin 2296f1580f4eSBarry Smith `MatSetNearNullSpace()` - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use 229749567fc5SPierre Jolivet the following two options: ``-pc_hypre_boomeramg_nodal_coarsen <n> -pc_hypre_boomeramg_vec_interp_variant <v>`` 22980b1a5bd9SEric Chamberland 2299f1580f4eSBarry Smith See `PCPFMG`, `PCSMG`, and `PCSYSPFMG` for access to hypre's other (nonalgebraic) multigrid solvers 2300f1580f4eSBarry Smith 2301f1580f4eSBarry Smith For `PCHYPRE` type of ams or ads auxiliary data must be provided to the preconditioner with `PCHYPRESetDiscreteGradient()`, 2302f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 230349567fc5SPierre Jolivet `PCHYPREAMSSetInteriorNodes()` 2304f1580f4eSBarry Smith 2305f1580f4eSBarry Smith PETSc provides its own geometric and algebraic multigrid solvers `PCMG` and `PCGAMG`, also see `PCHMG` which is useful for certain multicomponent problems 23069e5bc791SBarry Smith 2307ead8c081SBarry Smith GPU Notes: 2308ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda 2309f1580f4eSBarry Smith Then pass `VECCUDA` vectors and `MATAIJCUSPARSE` matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2310ead8c081SBarry Smith 2311ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip 2312f1580f4eSBarry Smith Then pass `VECHIP` vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2313ead8c081SBarry Smith 2314f1580f4eSBarry Smith .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRESetType()`, `PCPFMG`, `PCGAMG`, `PCSYSPFMG`, `PCSMG`, `PCHYPRESetDiscreteGradient()`, 2315f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 2316f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes() 231716d9e3a6SLisandro Dalcin M*/ 231816d9e3a6SLisandro Dalcin 2319d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 2320d71ae5a4SJacob Faibussowitsch { 232116d9e3a6SLisandro Dalcin PC_HYPRE *jac; 232216d9e3a6SLisandro Dalcin 232316d9e3a6SLisandro Dalcin PetscFunctionBegin; 23244dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac)); 23252fa5cd67SKarl Rupp 232616d9e3a6SLisandro Dalcin pc->data = jac; 23278695de01SBarry Smith pc->ops->reset = PCReset_HYPRE; 232816d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 232916d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 233016d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 233116d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 233216d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 23339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", PCHYPRESetType_HYPRE)); 23349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", PCHYPREGetType_HYPRE)); 23359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", PCSetCoordinates_HYPRE)); 23369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", PCHYPRESetDiscreteGradient_HYPRE)); 23379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", PCHYPRESetDiscreteCurl_HYPRE)); 23389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", PCHYPRESetInterpolations_HYPRE)); 23399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", PCHYPRESetEdgeConstantVectors_HYPRE)); 2340be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", PCHYPREAMSSetInteriorNodes_HYPRE)); 23419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", PCHYPRESetPoissonMatrix_HYPRE)); 23429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG)); 23439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG)); 23446ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 23456ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 23469566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 23476ea7df73SStefano Zampini #endif 23486ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 23499566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 23506ea7df73SStefano Zampini #endif 23516ea7df73SStefano Zampini #endif 2352*ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 23533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 235416d9e3a6SLisandro Dalcin } 2355ebc551c0SBarry Smith 2356ebc551c0SBarry Smith typedef struct { 235768326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 2358f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 23599e5bc791SBarry Smith 23609e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 23614ddd07fcSJed Brown PetscInt its; 23629e5bc791SBarry Smith double tol; 23634ddd07fcSJed Brown PetscInt relax_type; 23644ddd07fcSJed Brown PetscInt rap_type; 23654ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 23664ddd07fcSJed Brown PetscInt max_levels; 23670be8cd64Sftrigaux PetscInt skip_relax; 23680be8cd64Sftrigaux PetscBool print_statistics; 2369ebc551c0SBarry Smith } PC_PFMG; 2370ebc551c0SBarry Smith 2371d71ae5a4SJacob Faibussowitsch PetscErrorCode PCDestroy_PFMG(PC pc) 2372d71ae5a4SJacob Faibussowitsch { 2373f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2374ebc551c0SBarry Smith 2375ebc551c0SBarry Smith PetscFunctionBegin; 2376792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 23779566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 23789566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 23793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2380ebc551c0SBarry Smith } 2381ebc551c0SBarry Smith 23829e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi", "Weighted-Jacobi", "symmetric-Red/Black-Gauss-Seidel", "Red/Black-Gauss-Seidel"}; 23839e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin", "non-Galerkin"}; 23849e5bc791SBarry Smith 2385d71ae5a4SJacob Faibussowitsch PetscErrorCode PCView_PFMG(PC pc, PetscViewer viewer) 2386d71ae5a4SJacob Faibussowitsch { 2387ace3abfcSBarry Smith PetscBool iascii; 2388f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2389ebc551c0SBarry Smith 2390ebc551c0SBarry Smith PetscFunctionBegin; 23919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 23929e5bc791SBarry Smith if (iascii) { 23939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE PFMG preconditioning\n")); 239463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 23959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 23969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 23979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " RAP type %s\n", PFMGRAPType[ex->rap_type])); 239863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 239963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max levels %" PetscInt_FMT "\n", ex->max_levels)); 24000be8cd64Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " skip relax %" PetscInt_FMT "\n", ex->skip_relax)); 24019e5bc791SBarry Smith } 24023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2403ebc551c0SBarry Smith } 2404ebc551c0SBarry Smith 2405d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetFromOptions_PFMG(PC pc, PetscOptionItems *PetscOptionsObject) 2406d71ae5a4SJacob Faibussowitsch { 2407f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2408ebc551c0SBarry Smith 2409ebc551c0SBarry Smith PetscFunctionBegin; 2410d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PFMG options"); 24110be8cd64Sftrigaux PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics", "Print statistics", "HYPRE_StructPFMGSetPrintLevel", ex->print_statistics, &ex->print_statistics, NULL)); 24129566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_its", "Number of iterations of PFMG to use as preconditioner", "HYPRE_StructPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2413792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 24149566063dSJacob 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)); 2415792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 24169566063dSJacob 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)); 2417792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 24189e5bc791SBarry Smith 24199566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_max_levels", "Max Levels for MG hierarchy", "HYPRE_StructPFMGSetMaxLevels", ex->max_levels, &ex->max_levels, NULL)); 2420792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 24213b46a515SGlenn Hammond 24229566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_pfmg_tol", "Tolerance of PFMG", "HYPRE_StructPFMGSetTol", ex->tol, &ex->tol, NULL)); 2423792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 2424dd39110bSPierre 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)); 2425792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 2426dd39110bSPierre 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)); 2427792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 24280be8cd64Sftrigaux 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)); 24290be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetSkipRelax, ex->hsolver, ex->skip_relax); 2430d0609cedSBarry Smith PetscOptionsHeadEnd(); 24313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2432ebc551c0SBarry Smith } 2433ebc551c0SBarry Smith 2434d71ae5a4SJacob Faibussowitsch PetscErrorCode PCApply_PFMG(PC pc, Vec x, Vec y) 2435d71ae5a4SJacob Faibussowitsch { 2436f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2437d9ca1df4SBarry Smith PetscScalar *yy; 2438d9ca1df4SBarry Smith const PetscScalar *xx; 24394ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 24402cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 244168326731SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 2442f91d8e95SBarry Smith 2443f91d8e95SBarry Smith PetscFunctionBegin; 24449566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 24459566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 24462cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2447f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 2448f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 2449f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 24502cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 24512cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 24522cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 24532cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 24542cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 24552cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2456f91d8e95SBarry Smith 2457f91d8e95SBarry Smith /* copy x values over to hypre */ 2458792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 24599566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2460792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 24619566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2462792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 2463792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2464f91d8e95SBarry Smith 2465f91d8e95SBarry Smith /* copy solution values back to PETSc */ 24669566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2467792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 24689566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 24693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2470f91d8e95SBarry Smith } 2471f91d8e95SBarry Smith 2472d71ae5a4SJacob 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) 2473d71ae5a4SJacob Faibussowitsch { 24749e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG *)pc->data; 24752cf14000SStefano Zampini HYPRE_Int oits; 24769e5bc791SBarry Smith 24779e5bc791SBarry Smith PetscFunctionBegin; 24789566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 2479792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, its * jac->its); 2480792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, rtol); 24819e5bc791SBarry Smith 24829566063dSJacob Faibussowitsch PetscCall(PCApply_PFMG(pc, b, y)); 2483792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGGetNumIterations, jac->hsolver, &oits); 24849e5bc791SBarry Smith *outits = oits; 24859e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 24869e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 2487792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, jac->tol); 2488792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, jac->its); 24893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24909e5bc791SBarry Smith } 24919e5bc791SBarry Smith 2492d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetUp_PFMG(PC pc) 2493d71ae5a4SJacob Faibussowitsch { 24943a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG *)pc->data; 24953a32d3dbSGlenn Hammond Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 2496ace3abfcSBarry Smith PetscBool flg; 24973a32d3dbSGlenn Hammond 24983a32d3dbSGlenn Hammond PetscFunctionBegin; 24999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 250028b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 25013a32d3dbSGlenn Hammond 25023a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 2503792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 2504792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 25050be8cd64Sftrigaux 25060be8cd64Sftrigaux // Print Hypre statistics about the solve process 25070be8cd64Sftrigaux if (ex->print_statistics) PetscCallExternal(HYPRE_StructPFMGSetPrintLevel, ex->hsolver, 3); 25080be8cd64Sftrigaux 25090be8cd64Sftrigaux // The hypre options must be repeated here because the StructPFMG was destroyed and recreated 25100be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 25110be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 25120be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 25130be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 25140be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 25150be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 25160be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 25170be8cd64Sftrigaux 2518792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2519792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetZeroGuess, ex->hsolver); 25203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25213a32d3dbSGlenn Hammond } 25223a32d3dbSGlenn Hammond 2523ebc551c0SBarry Smith /*MC 2524ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 2525ebc551c0SBarry Smith 2526f1580f4eSBarry Smith Options Database Keys: 252767b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner 252867b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve 252967b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve 253067b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG 25319e5bc791SBarry 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 25320be8cd64Sftrigaux . -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 2533f1580f4eSBarry Smith - -pc_pfmg_skip_relax - skip relaxation on certain grids for isotropic problems. This can greatly improve efficiency by eliminating unnecessary relaxations 2534f1580f4eSBarry Smith when the underlying problem is isotropic, one of 0,1 2535f1580f4eSBarry Smith 2536f1580f4eSBarry Smith Level: advanced 2537f91d8e95SBarry Smith 253895452b02SPatrick Sanan Notes: 253995452b02SPatrick Sanan This is for CELL-centered descretizations 25409e5bc791SBarry Smith 2541f1580f4eSBarry Smith See `PCSYSPFMG` for a version suitable for systems of PDEs, and `PCSMG` 25429e5bc791SBarry Smith 2543f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 2544f1580f4eSBarry Smith 2545f1580f4eSBarry Smith This must be used with the `MATHYPRESTRUCT` matrix type. 2546f1580f4eSBarry Smith 2547f1580f4eSBarry Smith This provides only some of the functionality of PFMG, it supports only one block per process defined by a PETSc `DMDA`. 2548f1580f4eSBarry Smith 2549f1580f4eSBarry Smith .seealso: `PCMG`, `MATHYPRESTRUCT`, `PCHYPRE`, `PCGAMG`, `PCSYSPFMG`, `PCSMG` 2550ebc551c0SBarry Smith M*/ 2551ebc551c0SBarry Smith 2552d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 2553d71ae5a4SJacob Faibussowitsch { 2554ebc551c0SBarry Smith PC_PFMG *ex; 2555ebc551c0SBarry Smith 2556ebc551c0SBarry Smith PetscFunctionBegin; 25579371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 255868326731SBarry Smith pc->data = ex; 2559ebc551c0SBarry Smith 25609e5bc791SBarry Smith ex->its = 1; 25619e5bc791SBarry Smith ex->tol = 1.e-8; 25629e5bc791SBarry Smith ex->relax_type = 1; 25639e5bc791SBarry Smith ex->rap_type = 0; 25649e5bc791SBarry Smith ex->num_pre_relax = 1; 25659e5bc791SBarry Smith ex->num_post_relax = 1; 25663b46a515SGlenn Hammond ex->max_levels = 0; 25670be8cd64Sftrigaux ex->skip_relax = 0; 25680be8cd64Sftrigaux ex->print_statistics = PETSC_FALSE; 25699e5bc791SBarry Smith 2570ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 2571ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 2572ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 2573f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 25749e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 257568326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 25762fa5cd67SKarl Rupp 25779566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 2578*ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 2579792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 25803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2581ebc551c0SBarry Smith } 2582d851a50bSGlenn Hammond 2583d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 2584d851a50bSGlenn Hammond typedef struct { 2585d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 2586d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 2587d851a50bSGlenn Hammond 2588d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 25894ddd07fcSJed Brown PetscInt its; 2590d851a50bSGlenn Hammond double tol; 25914ddd07fcSJed Brown PetscInt relax_type; 25924ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 2593d851a50bSGlenn Hammond } PC_SysPFMG; 2594d851a50bSGlenn Hammond 2595d71ae5a4SJacob Faibussowitsch PetscErrorCode PCDestroy_SysPFMG(PC pc) 2596d71ae5a4SJacob Faibussowitsch { 2597d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2598d851a50bSGlenn Hammond 2599d851a50bSGlenn Hammond PetscFunctionBegin; 2600792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 26019566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 26029566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 26033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2604d851a50bSGlenn Hammond } 2605d851a50bSGlenn Hammond 2606d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi", "Red/Black-Gauss-Seidel"}; 2607d851a50bSGlenn Hammond 2608d71ae5a4SJacob Faibussowitsch PetscErrorCode PCView_SysPFMG(PC pc, PetscViewer viewer) 2609d71ae5a4SJacob Faibussowitsch { 2610ace3abfcSBarry Smith PetscBool iascii; 2611d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2612d851a50bSGlenn Hammond 2613d851a50bSGlenn Hammond PetscFunctionBegin; 26149566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 2615d851a50bSGlenn Hammond if (iascii) { 26169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SysPFMG preconditioning\n")); 261763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 26189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 26199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 262063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 2621d851a50bSGlenn Hammond } 26223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2623d851a50bSGlenn Hammond } 2624d851a50bSGlenn Hammond 2625d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetFromOptions_SysPFMG(PC pc, PetscOptionItems *PetscOptionsObject) 2626d71ae5a4SJacob Faibussowitsch { 2627d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2628ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2629d851a50bSGlenn Hammond 2630d851a50bSGlenn Hammond PetscFunctionBegin; 2631d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SysPFMG options"); 26329566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics", "Print statistics", "HYPRE_SStructSysPFMGSetPrintLevel", flg, &flg, NULL)); 263348a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_SStructSysPFMGSetPrintLevel, ex->ss_solver, 3); 26349566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_its", "Number of iterations of SysPFMG to use as preconditioner", "HYPRE_SStructSysPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2635792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, ex->ss_solver, ex->its); 26369566063dSJacob 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)); 2637792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPreRelax, ex->ss_solver, ex->num_pre_relax); 26389566063dSJacob 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)); 2639792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPostRelax, ex->ss_solver, ex->num_post_relax); 2640d851a50bSGlenn Hammond 26419566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_syspfmg_tol", "Tolerance of SysPFMG", "HYPRE_SStructSysPFMGSetTol", ex->tol, &ex->tol, NULL)); 2642792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, ex->ss_solver, ex->tol); 2643dd39110bSPierre 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)); 2644792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetRelaxType, ex->ss_solver, ex->relax_type); 2645d0609cedSBarry Smith PetscOptionsHeadEnd(); 26463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2647d851a50bSGlenn Hammond } 2648d851a50bSGlenn Hammond 2649d71ae5a4SJacob Faibussowitsch PetscErrorCode PCApply_SysPFMG(PC pc, Vec x, Vec y) 2650d71ae5a4SJacob Faibussowitsch { 2651d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2652d9ca1df4SBarry Smith PetscScalar *yy; 2653d9ca1df4SBarry Smith const PetscScalar *xx; 26544ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 26552cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 2656d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)(pc->pmat->data); 26574ddd07fcSJed Brown PetscInt ordering = mx->dofs_order; 26584ddd07fcSJed Brown PetscInt nvars = mx->nvars; 26594ddd07fcSJed Brown PetscInt part = 0; 26604ddd07fcSJed Brown PetscInt size; 26614ddd07fcSJed Brown PetscInt i; 2662d851a50bSGlenn Hammond 2663d851a50bSGlenn Hammond PetscFunctionBegin; 26649566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 26659566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 26662cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2667d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 2668d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 2669d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 26702cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 26712cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 26722cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 26732cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 26742cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 26752cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2676d851a50bSGlenn Hammond 2677d851a50bSGlenn Hammond size = 1; 26782fa5cd67SKarl Rupp for (i = 0; i < 3; i++) size *= (iupper[i] - ilower[i] + 1); 26792fa5cd67SKarl Rupp 2680d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 2681d851a50bSGlenn Hammond if (ordering) { 2682792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 26839566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2684792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(xx + (size * i))); 26859566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2686792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 2687792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructMatrixMatvec, 1.0, mx->ss_mat, mx->ss_b, 0.0, mx->ss_x); 2688792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 2689d851a50bSGlenn Hammond 2690d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 26919566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2692792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(yy + (size * i))); 26939566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 2694a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 2695d851a50bSGlenn Hammond PetscScalar *z; 26964ddd07fcSJed Brown PetscInt j, k; 2697d851a50bSGlenn Hammond 26989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvars * size, &z)); 2699792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 27009566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2701d851a50bSGlenn Hammond 2702d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 2703d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 2704d851a50bSGlenn Hammond k = i * nvars; 27052fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) z[j * size + i] = xx[k + j]; 2706d851a50bSGlenn Hammond } 2707792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 27089566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2709792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 2710792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 2711d851a50bSGlenn Hammond 2712d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 27139566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2714792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 2715d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 2716d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 2717d851a50bSGlenn Hammond k = i * nvars; 27182fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) yy[k + j] = z[j * size + i]; 2719d851a50bSGlenn Hammond } 27209566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 27219566063dSJacob Faibussowitsch PetscCall(PetscFree(z)); 2722d851a50bSGlenn Hammond } 27233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2724d851a50bSGlenn Hammond } 2725d851a50bSGlenn Hammond 2726d71ae5a4SJacob 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) 2727d71ae5a4SJacob Faibussowitsch { 2728d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG *)pc->data; 27292cf14000SStefano Zampini HYPRE_Int oits; 2730d851a50bSGlenn Hammond 2731d851a50bSGlenn Hammond PetscFunctionBegin; 27329566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 2733792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, its * jac->its); 2734792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, rtol); 27359566063dSJacob Faibussowitsch PetscCall(PCApply_SysPFMG(pc, b, y)); 2736792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGGetNumIterations, jac->ss_solver, &oits); 2737d851a50bSGlenn Hammond *outits = oits; 2738d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 2739d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 2740792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, jac->tol); 2741792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, jac->its); 27423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2743d851a50bSGlenn Hammond } 2744d851a50bSGlenn Hammond 2745d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetUp_SysPFMG(PC pc) 2746d71ae5a4SJacob Faibussowitsch { 2747d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2748d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)(pc->pmat->data); 2749ace3abfcSBarry Smith PetscBool flg; 2750d851a50bSGlenn Hammond 2751d851a50bSGlenn Hammond PetscFunctionBegin; 27529566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESSTRUCT, &flg)); 275328b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESSTRUCT with this preconditioner"); 2754d851a50bSGlenn Hammond 2755d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 2756792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 2757792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 2758792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetZeroGuess, ex->ss_solver); 2759792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetup, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 27603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2761d851a50bSGlenn Hammond } 2762d851a50bSGlenn Hammond 2763d851a50bSGlenn Hammond /*MC 2764f1580f4eSBarry Smith PCSYSPFMG - the hypre SysPFMG multigrid solver 2765d851a50bSGlenn Hammond 2766d851a50bSGlenn Hammond Level: advanced 2767d851a50bSGlenn Hammond 2768f1580f4eSBarry Smith Options Database Keys: 276967b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner 277067b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid 277167b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid 277267b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG 277367b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles 2774d851a50bSGlenn Hammond 277595452b02SPatrick Sanan Notes: 2776f1580f4eSBarry Smith See `PCPFMG` for hypre's PFMG that works for a scalar PDE and `PCSMG` 2777f1580f4eSBarry Smith 2778f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 2779f1580f4eSBarry Smith 278095452b02SPatrick Sanan This is for CELL-centered descretizations 2781d851a50bSGlenn Hammond 2782f1580f4eSBarry Smith This must be used with the `MATHYPRESSTRUCT` matrix type. 2783d851a50bSGlenn Hammond 2784f1580f4eSBarry 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`. 2785f1580f4eSBarry Smith 2786f1580f4eSBarry Smith .seealso: `PCMG`, `MATHYPRESSTRUCT`, `PCPFMG`, `PCHYPRE`, `PCGAMG`, `PCSMG` 2787d851a50bSGlenn Hammond M*/ 2788d851a50bSGlenn Hammond 2789d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 2790d71ae5a4SJacob Faibussowitsch { 2791d851a50bSGlenn Hammond PC_SysPFMG *ex; 2792d851a50bSGlenn Hammond 2793d851a50bSGlenn Hammond PetscFunctionBegin; 27949371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 2795d851a50bSGlenn Hammond pc->data = ex; 2796d851a50bSGlenn Hammond 2797d851a50bSGlenn Hammond ex->its = 1; 2798d851a50bSGlenn Hammond ex->tol = 1.e-8; 2799d851a50bSGlenn Hammond ex->relax_type = 1; 2800d851a50bSGlenn Hammond ex->num_pre_relax = 1; 2801d851a50bSGlenn Hammond ex->num_post_relax = 1; 2802d851a50bSGlenn Hammond 2803d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 2804d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 2805d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 2806d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 2807d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 2808d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 28092fa5cd67SKarl Rupp 28109566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 2811*ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 2812792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 28133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2814d851a50bSGlenn Hammond } 28151c188c59Sftrigaux 2816f1580f4eSBarry Smith /* PC SMG */ 28171c188c59Sftrigaux typedef struct { 28181c188c59Sftrigaux MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 28191c188c59Sftrigaux HYPRE_StructSolver hsolver; 28201c188c59Sftrigaux PetscInt its; /* keep copy of SMG options used so may view them */ 28211c188c59Sftrigaux double tol; 28221c188c59Sftrigaux PetscBool print_statistics; 28231c188c59Sftrigaux PetscInt num_pre_relax, num_post_relax; 28241c188c59Sftrigaux } PC_SMG; 28251c188c59Sftrigaux 2826d71ae5a4SJacob Faibussowitsch PetscErrorCode PCDestroy_SMG(PC pc) 2827d71ae5a4SJacob Faibussowitsch { 28281c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 28291c188c59Sftrigaux 28301c188c59Sftrigaux PetscFunctionBegin; 28311c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, ex->hsolver); 28321c188c59Sftrigaux PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 28331c188c59Sftrigaux PetscCall(PetscFree(pc->data)); 28343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28351c188c59Sftrigaux } 28361c188c59Sftrigaux 2837d71ae5a4SJacob Faibussowitsch PetscErrorCode PCView_SMG(PC pc, PetscViewer viewer) 2838d71ae5a4SJacob Faibussowitsch { 28391c188c59Sftrigaux PetscBool iascii; 28401c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 28411c188c59Sftrigaux 28421c188c59Sftrigaux PetscFunctionBegin; 28431c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 28441c188c59Sftrigaux if (iascii) { 28451c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SMG preconditioning\n")); 28461c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 28471c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 28481c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 28491c188c59Sftrigaux } 28503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28511c188c59Sftrigaux } 28521c188c59Sftrigaux 2853d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetFromOptions_SMG(PC pc, PetscOptionItems *PetscOptionsObject) 2854d71ae5a4SJacob Faibussowitsch { 28551c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 28561c188c59Sftrigaux 28571c188c59Sftrigaux PetscFunctionBegin; 28581c188c59Sftrigaux PetscOptionsHeadBegin(PetscOptionsObject, "SMG options"); 28591c188c59Sftrigaux 28601c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_its", "Number of iterations of SMG to use as preconditioner", "HYPRE_StructSMGSetMaxIter", ex->its, &ex->its, NULL)); 28611c188c59Sftrigaux 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)); 28621c188c59Sftrigaux 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)); 28631c188c59Sftrigaux PetscCall(PetscOptionsReal("-pc_smg_tol", "Tolerance of SMG", "HYPRE_StructSMGSetTol", ex->tol, &ex->tol, NULL)); 28641c188c59Sftrigaux 28651c188c59Sftrigaux PetscOptionsHeadEnd(); 28663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28671c188c59Sftrigaux } 28681c188c59Sftrigaux 2869d71ae5a4SJacob Faibussowitsch PetscErrorCode PCApply_SMG(PC pc, Vec x, Vec y) 2870d71ae5a4SJacob Faibussowitsch { 28711c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 28721c188c59Sftrigaux PetscScalar *yy; 28731c188c59Sftrigaux const PetscScalar *xx; 28741c188c59Sftrigaux PetscInt ilower[3], iupper[3]; 28751c188c59Sftrigaux HYPRE_Int hlower[3], hupper[3]; 28761c188c59Sftrigaux Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 28771c188c59Sftrigaux 28781c188c59Sftrigaux PetscFunctionBegin; 28791c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 28801c188c59Sftrigaux PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 28811c188c59Sftrigaux /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 28821c188c59Sftrigaux iupper[0] += ilower[0] - 1; 28831c188c59Sftrigaux iupper[1] += ilower[1] - 1; 28841c188c59Sftrigaux iupper[2] += ilower[2] - 1; 28851c188c59Sftrigaux hlower[0] = (HYPRE_Int)ilower[0]; 28861c188c59Sftrigaux hlower[1] = (HYPRE_Int)ilower[1]; 28871c188c59Sftrigaux hlower[2] = (HYPRE_Int)ilower[2]; 28881c188c59Sftrigaux hupper[0] = (HYPRE_Int)iupper[0]; 28891c188c59Sftrigaux hupper[1] = (HYPRE_Int)iupper[1]; 28901c188c59Sftrigaux hupper[2] = (HYPRE_Int)iupper[2]; 28911c188c59Sftrigaux 28921c188c59Sftrigaux /* copy x values over to hypre */ 28931c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 28941c188c59Sftrigaux PetscCall(VecGetArrayRead(x, &xx)); 28951c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 28961c188c59Sftrigaux PetscCall(VecRestoreArrayRead(x, &xx)); 28971c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 28981c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 28991c188c59Sftrigaux 29001c188c59Sftrigaux /* copy solution values back to PETSc */ 29011c188c59Sftrigaux PetscCall(VecGetArray(y, &yy)); 29021c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 29031c188c59Sftrigaux PetscCall(VecRestoreArray(y, &yy)); 29043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29051c188c59Sftrigaux } 29061c188c59Sftrigaux 2907d71ae5a4SJacob 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) 2908d71ae5a4SJacob Faibussowitsch { 29091c188c59Sftrigaux PC_SMG *jac = (PC_SMG *)pc->data; 29101c188c59Sftrigaux HYPRE_Int oits; 29111c188c59Sftrigaux 29121c188c59Sftrigaux PetscFunctionBegin; 29131c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 29141c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, its * jac->its); 29151c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, rtol); 29161c188c59Sftrigaux 29171c188c59Sftrigaux PetscCall(PCApply_SMG(pc, b, y)); 29181c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGGetNumIterations, jac->hsolver, &oits); 29191c188c59Sftrigaux *outits = oits; 29201c188c59Sftrigaux if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 29211c188c59Sftrigaux else *reason = PCRICHARDSON_CONVERGED_RTOL; 29221c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, jac->tol); 29231c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, jac->its); 29243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29251c188c59Sftrigaux } 29261c188c59Sftrigaux 2927d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetUp_SMG(PC pc) 2928d71ae5a4SJacob Faibussowitsch { 29291c188c59Sftrigaux PetscInt i, dim; 29301c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 29311c188c59Sftrigaux Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 29321c188c59Sftrigaux PetscBool flg; 29331c188c59Sftrigaux DMBoundaryType p[3]; 29341c188c59Sftrigaux PetscInt M[3]; 29351c188c59Sftrigaux 29361c188c59Sftrigaux PetscFunctionBegin; 29371c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 29381c188c59Sftrigaux PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 29391c188c59Sftrigaux 29401c188c59Sftrigaux PetscCall(DMDAGetInfo(mx->da, &dim, &M[0], &M[1], &M[2], 0, 0, 0, 0, 0, &p[0], &p[1], &p[2], 0)); 29411c188c59Sftrigaux // Check if power of 2 in periodic directions 29421c188c59Sftrigaux for (i = 0; i < dim; i++) { 29431c188c59Sftrigaux if (((M[i] & (M[i] - 1)) != 0) && (p[i] == DM_BOUNDARY_PERIODIC)) { 29441c188c59Sftrigaux 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]); 29451c188c59Sftrigaux } 29461c188c59Sftrigaux } 29471c188c59Sftrigaux 29481c188c59Sftrigaux /* create the hypre solver object and set its information */ 29491c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, (ex->hsolver)); 29501c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 29511c188c59Sftrigaux // The hypre options must be set here and not in SetFromOptions because it is created here! 29521c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, ex->hsolver, ex->its); 29531c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 29541c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 29551c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, ex->hsolver, ex->tol); 29561c188c59Sftrigaux 29571c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 29581c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetZeroGuess, ex->hsolver); 29593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29601c188c59Sftrigaux } 29611c188c59Sftrigaux 29621c188c59Sftrigaux /*MC 29635cb80ecdSBarry Smith PCSMG - the hypre (structured grid) SMG multigrid solver 29641c188c59Sftrigaux 29651c188c59Sftrigaux Level: advanced 29661c188c59Sftrigaux 2967f1580f4eSBarry Smith Options Database Keys: 29685cb80ecdSBarry Smith + -pc_smg_its <its> - number of iterations of SMG to use as preconditioner 29695cb80ecdSBarry Smith . -pc_smg_num_pre_relax <steps> - number of smoothing steps before coarse grid 29705cb80ecdSBarry Smith . -pc_smg_num_post_relax <steps> - number of smoothing steps after coarse grid 29715cb80ecdSBarry Smith - -pc_smg_tol <tol> - tolerance of SMG 29721c188c59Sftrigaux 29731c188c59Sftrigaux Notes: 29741c188c59Sftrigaux This is for CELL-centered descretizations 29751c188c59Sftrigaux 29765cb80ecdSBarry Smith This must be used with the `MATHYPRESTRUCT` `MatType`. 29771c188c59Sftrigaux 2978f1580f4eSBarry 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`. 2979f1580f4eSBarry Smith 2980f1580f4eSBarry Smith See `PCSYSPFMG`, `PCSMG`, `PCPFMG`, and `PCHYPRE` for access to hypre's other preconditioners 2981f1580f4eSBarry Smith 2982f1580f4eSBarry Smith .seealso: `PCMG`, `MATHYPRESTRUCT`, `PCPFMG`, `PCSYSPFMG`, `PCHYPRE`, `PCGAMG` 29831c188c59Sftrigaux M*/ 29841c188c59Sftrigaux 2985d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SMG(PC pc) 2986d71ae5a4SJacob Faibussowitsch { 29871c188c59Sftrigaux PC_SMG *ex; 29881c188c59Sftrigaux 29891c188c59Sftrigaux PetscFunctionBegin; 29909371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 29911c188c59Sftrigaux pc->data = ex; 29921c188c59Sftrigaux 29931c188c59Sftrigaux ex->its = 1; 29941c188c59Sftrigaux ex->tol = 1.e-8; 29951c188c59Sftrigaux ex->num_pre_relax = 1; 29961c188c59Sftrigaux ex->num_post_relax = 1; 29971c188c59Sftrigaux 29981c188c59Sftrigaux pc->ops->setfromoptions = PCSetFromOptions_SMG; 29991c188c59Sftrigaux pc->ops->view = PCView_SMG; 30001c188c59Sftrigaux pc->ops->destroy = PCDestroy_SMG; 30011c188c59Sftrigaux pc->ops->apply = PCApply_SMG; 30021c188c59Sftrigaux pc->ops->applyrichardson = PCApplyRichardson_SMG; 30031c188c59Sftrigaux pc->ops->setup = PCSetUp_SMG; 30041c188c59Sftrigaux 30051c188c59Sftrigaux PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 3006*ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 30071c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 30083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30091c188c59Sftrigaux } 3010