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; 21a8d69d7bSBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n title = {{\\sl hypre}: High Performance Preconditioners},\n organization = {Lawrence Livermore National Laboratory},\n note = {\\url{https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods}}\n}\n"; 221f817a21SBarry Smith 2316d9e3a6SLisandro Dalcin /* 2416d9e3a6SLisandro Dalcin Private context (data structure) for the preconditioner. 2516d9e3a6SLisandro Dalcin */ 2616d9e3a6SLisandro Dalcin typedef struct { 2716d9e3a6SLisandro Dalcin HYPRE_Solver hsolver; 2849a781f5SStefano Zampini Mat hpmat; /* MatHYPRE */ 2916d9e3a6SLisandro Dalcin 304ddd07fcSJed Brown HYPRE_Int (*destroy)(HYPRE_Solver); 314ddd07fcSJed Brown HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 324ddd07fcSJed Brown HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 3316d9e3a6SLisandro Dalcin 3416d9e3a6SLisandro Dalcin MPI_Comm comm_hypre; 3516d9e3a6SLisandro Dalcin char *hypre_type; 3616d9e3a6SLisandro Dalcin 3716d9e3a6SLisandro Dalcin /* options for Pilut and BoomerAMG*/ 384ddd07fcSJed Brown PetscInt maxiter; 3939accc25SStefano Zampini PetscReal tol; 4016d9e3a6SLisandro Dalcin 4116d9e3a6SLisandro Dalcin /* options for Pilut */ 424ddd07fcSJed Brown PetscInt factorrowsize; 4316d9e3a6SLisandro Dalcin 4416d9e3a6SLisandro Dalcin /* options for ParaSails */ 454ddd07fcSJed Brown PetscInt nlevels; 468966356dSPierre Jolivet PetscReal threshold; 4739accc25SStefano Zampini PetscReal filter; 4839accc25SStefano Zampini PetscReal loadbal; 494ddd07fcSJed Brown PetscInt logging; 504ddd07fcSJed Brown PetscInt ruse; 514ddd07fcSJed Brown PetscInt symt; 5216d9e3a6SLisandro Dalcin 5322b6d1caSBarry Smith /* options for BoomerAMG */ 54ace3abfcSBarry Smith PetscBool printstatistics; 5516d9e3a6SLisandro Dalcin 5616d9e3a6SLisandro Dalcin /* options for BoomerAMG */ 574ddd07fcSJed Brown PetscInt cycletype; 584ddd07fcSJed Brown PetscInt maxlevels; 5939accc25SStefano Zampini PetscReal strongthreshold; 6039accc25SStefano Zampini PetscReal maxrowsum; 614ddd07fcSJed Brown PetscInt gridsweeps[3]; 624ddd07fcSJed Brown PetscInt coarsentype; 634ddd07fcSJed Brown PetscInt measuretype; 646a251517SEike Mueller PetscInt smoothtype; 658131ecf7SEike Mueller PetscInt smoothnumlevels; 66ec64516dSEike Mueller PetscInt eu_level; /* Number of levels for ILU(k) in Euclid */ 6739accc25SStefano Zampini PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */ 68ec64516dSEike Mueller PetscInt eu_bj; /* Defines use of Block Jacobi ILU in Euclid */ 694ddd07fcSJed Brown PetscInt relaxtype[3]; 7039accc25SStefano Zampini PetscReal relaxweight; 7139accc25SStefano Zampini PetscReal outerrelaxweight; 724ddd07fcSJed Brown PetscInt relaxorder; 7339accc25SStefano Zampini PetscReal truncfactor; 74ace3abfcSBarry Smith PetscBool applyrichardson; 754ddd07fcSJed Brown PetscInt pmax; 764ddd07fcSJed Brown PetscInt interptype; 77589dcaf0SStefano Zampini PetscInt maxc; 78589dcaf0SStefano Zampini PetscInt minc; 79db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 80db6f9c32SMark Adams char *spgemm_type; // this is a global hypre parameter but is closely associated with BoomerAMG 81db6f9c32SMark Adams #endif 826ea7df73SStefano Zampini /* GPU */ 836ea7df73SStefano Zampini PetscBool keeptranspose; 846ea7df73SStefano Zampini PetscInt rap2; 856ea7df73SStefano Zampini PetscInt mod_rap2; 866ea7df73SStefano Zampini 87589dcaf0SStefano Zampini /* AIR */ 88589dcaf0SStefano Zampini PetscInt Rtype; 89589dcaf0SStefano Zampini PetscReal Rstrongthreshold; 90589dcaf0SStefano Zampini PetscReal Rfilterthreshold; 91589dcaf0SStefano Zampini PetscInt Adroptype; 92589dcaf0SStefano Zampini PetscReal Adroptol; 93589dcaf0SStefano Zampini 944ddd07fcSJed Brown PetscInt agg_nl; 956ea7df73SStefano Zampini PetscInt agg_interptype; 964ddd07fcSJed Brown PetscInt agg_num_paths; 97ace3abfcSBarry Smith PetscBool nodal_relax; 984ddd07fcSJed Brown PetscInt nodal_relax_levels; 994cb006feSStefano Zampini 1005272c319SBarry Smith PetscInt nodal_coarsening; 10122e51d31SStefano Zampini PetscInt nodal_coarsening_diag; 1025272c319SBarry Smith PetscInt vec_interp_variant; 10322e51d31SStefano Zampini PetscInt vec_interp_qmax; 10422e51d31SStefano Zampini PetscBool vec_interp_smooth; 10522e51d31SStefano Zampini PetscInt interp_refine; 10622e51d31SStefano Zampini 1076ea7df73SStefano Zampini /* NearNullSpace support */ 1086ea7df73SStefano Zampini VecHYPRE_IJVector *hmnull; 1096ea7df73SStefano Zampini HYPRE_ParVector *phmnull; 1105272c319SBarry Smith PetscInt n_hmnull; 1115272c319SBarry Smith Vec hmnull_constant; 1125272c319SBarry Smith 113863406b8SStefano Zampini /* options for AS (Auxiliary Space preconditioners) */ 114863406b8SStefano Zampini PetscInt as_print; 115863406b8SStefano Zampini PetscInt as_max_iter; 116863406b8SStefano Zampini PetscReal as_tol; 117863406b8SStefano Zampini PetscInt as_relax_type; 118863406b8SStefano Zampini PetscInt as_relax_times; 119863406b8SStefano Zampini PetscReal as_relax_weight; 120863406b8SStefano Zampini PetscReal as_omega; 121863406b8SStefano 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) */ 122863406b8SStefano Zampini PetscReal as_amg_alpha_theta; /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */ 123863406b8SStefano 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) */ 124863406b8SStefano Zampini PetscReal as_amg_beta_theta; /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS) */ 1254cb006feSStefano Zampini PetscInt ams_cycle_type; 126863406b8SStefano Zampini PetscInt ads_cycle_type; 1274cb006feSStefano Zampini 1284cb006feSStefano Zampini /* additional data */ 1295ac14e1cSStefano Zampini Mat G; /* MatHYPRE */ 1305ac14e1cSStefano Zampini Mat C; /* MatHYPRE */ 1315ac14e1cSStefano Zampini Mat alpha_Poisson; /* MatHYPRE */ 1325ac14e1cSStefano Zampini Mat beta_Poisson; /* MatHYPRE */ 1335ac14e1cSStefano Zampini 1345ac14e1cSStefano Zampini /* extra information for AMS */ 1355ac14e1cSStefano Zampini PetscInt dim; /* geometrical dimension */ 1366ea7df73SStefano Zampini VecHYPRE_IJVector coords[3]; 1376ea7df73SStefano Zampini VecHYPRE_IJVector constants[3]; 138be14dc20SKerry Key VecHYPRE_IJVector interior; 1396bf688a0SCe Qin Mat RT_PiFull, RT_Pi[3]; 1406bf688a0SCe Qin Mat ND_PiFull, ND_Pi[3]; 1414cb006feSStefano Zampini PetscBool ams_beta_is_zero; 14223df4f25SStefano Zampini PetscBool ams_beta_is_zero_part; 14323df4f25SStefano Zampini PetscInt ams_proj_freq; 14416d9e3a6SLisandro Dalcin } PC_HYPRE; 14516d9e3a6SLisandro Dalcin 146d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver) 147d2128fa2SBarry Smith { 148d2128fa2SBarry Smith PC_HYPRE *jac = (PC_HYPRE*)pc->data; 149d2128fa2SBarry Smith 150d2128fa2SBarry Smith PetscFunctionBegin; 151d2128fa2SBarry Smith *hsolver = jac->hsolver; 152d2128fa2SBarry Smith PetscFunctionReturn(0); 153d2128fa2SBarry Smith } 15416d9e3a6SLisandro Dalcin 155fd2dd295SFande Kong /* 1568a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1578a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1588a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 159fd2dd295SFande Kong */ 160fd2dd295SFande Kong static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt *nlevels,Mat *operators[]) 1618a2c336bSFande Kong { 1628a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1638a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1648a2c336bSFande Kong PetscInt num_levels,l; 1658a2c336bSFande Kong Mat *mattmp; 1668a2c336bSFande Kong hypre_ParCSRMatrix **A_array; 1678a2c336bSFande Kong 1688a2c336bSFande Kong PetscFunctionBegin; 1699566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type,"boomeramg",&same)); 1705f80ce2aSJacob Faibussowitsch PetscCheck(same,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG "); 1718a2c336bSFande Kong num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver)); 1729566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels,&mattmp)); 1738a2c336bSFande Kong A_array = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver)); 1748a2c336bSFande Kong for (l=1; l<num_levels; l++) { 1759566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l]))); 1768a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 1778a2c336bSFande Kong A_array[l] = NULL; 1788a2c336bSFande Kong } 1798a2c336bSFande Kong *nlevels = num_levels; 1808a2c336bSFande Kong *operators = mattmp; 1818a2c336bSFande Kong PetscFunctionReturn(0); 1828a2c336bSFande Kong } 1838a2c336bSFande Kong 184fd2dd295SFande Kong /* 1858a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1868a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1878a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 188fd2dd295SFande Kong */ 189fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[]) 1908a2c336bSFande Kong { 1918a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1928a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1938a2c336bSFande Kong PetscInt num_levels,l; 1948a2c336bSFande Kong Mat *mattmp; 1958a2c336bSFande Kong hypre_ParCSRMatrix **P_array; 1968a2c336bSFande Kong 1978a2c336bSFande Kong PetscFunctionBegin; 1989566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type,"boomeramg",&same)); 1995f80ce2aSJacob Faibussowitsch PetscCheck(same,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG "); 2008a2c336bSFande Kong num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver)); 2019566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels,&mattmp)); 2028a2c336bSFande Kong P_array = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver)); 2038a2c336bSFande Kong for (l=1; l<num_levels; l++) { 2049566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1]))); 2058a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 2068a2c336bSFande Kong P_array[num_levels-1-l] = NULL; 2078a2c336bSFande Kong } 2088a2c336bSFande Kong *nlevels = num_levels; 2098a2c336bSFande Kong *interpolations = mattmp; 2108a2c336bSFande Kong PetscFunctionReturn(0); 2118a2c336bSFande Kong } 2128a2c336bSFande Kong 213ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */ 214ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc) 215ce6a8a0dSJed Brown { 216ce6a8a0dSJed Brown PC_HYPRE *jac = (PC_HYPRE*)pc->data; 217ce6a8a0dSJed Brown PetscInt i; 218ce6a8a0dSJed Brown 2199d678128SJed Brown PetscFunctionBegin; 220ce6a8a0dSJed Brown for (i=0; i<jac->n_hmnull; i++) { 2219566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->hmnull[i])); 222ce6a8a0dSJed Brown } 2239566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hmnull)); 2249566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->phmnull)); 2259566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->hmnull_constant)); 2269d678128SJed Brown jac->n_hmnull = 0; 227ce6a8a0dSJed Brown PetscFunctionReturn(0); 228ce6a8a0dSJed Brown } 229ce6a8a0dSJed Brown 23016d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc) 23116d9e3a6SLisandro Dalcin { 23216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 23349a781f5SStefano Zampini Mat_HYPRE *hjac; 23416d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 23516d9e3a6SLisandro Dalcin HYPRE_ParVector bv,xv; 23649a781f5SStefano Zampini PetscBool ishypre; 23716d9e3a6SLisandro Dalcin 23816d9e3a6SLisandro Dalcin PetscFunctionBegin; 23916d9e3a6SLisandro Dalcin if (!jac->hypre_type) { 2409566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType(pc,"boomeramg")); 24116d9e3a6SLisandro Dalcin } 2425f5c5b43SBarry Smith 2439566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre)); 24449a781f5SStefano Zampini if (!ishypre) { 2459566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 2469566063dSJacob Faibussowitsch PetscCall(MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat)); 2479566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hpmat)); 24849a781f5SStefano Zampini } else { 2499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc->pmat)); 2509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 25149a781f5SStefano Zampini jac->hpmat = pc->pmat; 25216d9e3a6SLisandro Dalcin } 2536ea7df73SStefano Zampini /* allow debug */ 2549566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(jac->hpmat,NULL,"-pc_hypre_mat_view")); 25549a781f5SStefano Zampini hjac = (Mat_HYPRE*)(jac->hpmat->data); 2565f5c5b43SBarry Smith 25716d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 25816d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 2595272c319SBarry Smith MatNullSpace mnull; 2605272c319SBarry Smith PetscBool has_const; 26149a781f5SStefano Zampini PetscInt bs,nvec,i; 2625272c319SBarry Smith const Vec *vecs; 2635272c319SBarry Smith 2649566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat,&bs)); 265792fecdfSBarry Smith if (bs > 1) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs); 2669566063dSJacob Faibussowitsch PetscCall(MatGetNearNullSpace(pc->mat, &mnull)); 2675272c319SBarry Smith if (mnull) { 2689566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 2699566063dSJacob Faibussowitsch PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs)); 2709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec+1,&jac->hmnull)); 2719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec+1,&jac->phmnull)); 2725272c319SBarry Smith for (i=0; i<nvec; i++) { 2739566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map,&jac->hmnull[i])); 2749566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(vecs[i],jac->hmnull[i])); 275792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->hmnull[i]->ij,(void**)&jac->phmnull[i]); 2765272c319SBarry Smith } 2775272c319SBarry Smith if (has_const) { 2789566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL)); 2799566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hmnull_constant)); 2809566063dSJacob Faibussowitsch PetscCall(VecSet(jac->hmnull_constant,1)); 2819566063dSJacob Faibussowitsch PetscCall(VecNormalize(jac->hmnull_constant,NULL)); 2829566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map,&jac->hmnull[nvec])); 2839566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant,jac->hmnull[nvec])); 284792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->hmnull[nvec]->ij,(void**)&jac->phmnull[nvec]); 2855272c319SBarry Smith nvec++; 2865272c319SBarry Smith } 287792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVectors,jac->hsolver,nvec,jac->phmnull); 2885272c319SBarry Smith jac->n_hmnull = nvec; 2895272c319SBarry Smith } 2904cb006feSStefano Zampini } 291863406b8SStefano Zampini 2924cb006feSStefano Zampini /* special case for AMS */ 2934cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 2945ac14e1cSStefano Zampini Mat_HYPRE *hm; 2955ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 2966bf688a0SCe Qin if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 2976bf688a0SCe Qin 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"); 2986bf688a0SCe Qin } 2995ac14e1cSStefano Zampini if (jac->dim) { 300792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDimension,jac->hsolver,jac->dim); 3015ac14e1cSStefano Zampini } 3025ac14e1cSStefano Zampini if (jac->constants[0]) { 3035ac14e1cSStefano Zampini HYPRE_ParVector ozz,zoz,zzo = NULL; 304792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[0]->ij,(void**)(&ozz)); 305792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[1]->ij,(void**)(&zoz)); 3065ac14e1cSStefano Zampini if (jac->constants[2]) { 307792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[2]->ij,(void**)(&zzo)); 3085ac14e1cSStefano Zampini } 309792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetEdgeConstantVectors,jac->hsolver,ozz,zoz,zzo); 3105ac14e1cSStefano Zampini } 3115ac14e1cSStefano Zampini if (jac->coords[0]) { 3125ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3135ac14e1cSStefano Zampini coords[0] = NULL; 3145ac14e1cSStefano Zampini coords[1] = NULL; 3155ac14e1cSStefano Zampini coords[2] = NULL; 316792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0])); 317792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1])); 318792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2])); 319792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]); 3205ac14e1cSStefano Zampini } 3215f80ce2aSJacob Faibussowitsch PetscCheck(jac->G,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3225ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->G->data); 323792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 324792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDiscreteGradient,jac->hsolver,parcsr); 3255ac14e1cSStefano Zampini if (jac->alpha_Poisson) { 3265ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->alpha_Poisson->data); 327792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 328792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaPoissonMatrix,jac->hsolver,parcsr); 3295ac14e1cSStefano Zampini } 3305ac14e1cSStefano Zampini if (jac->ams_beta_is_zero) { 331792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,NULL); 3325ac14e1cSStefano Zampini } else if (jac->beta_Poisson) { 3335ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->beta_Poisson->data); 334792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 335792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,parcsr); 336be14dc20SKerry Key } else if (jac->ams_beta_is_zero_part) { 337be14dc20SKerry Key if (jac->interior) { 338be14dc20SKerry Key HYPRE_ParVector interior = NULL; 339be14dc20SKerry Key PetscCallExternal(HYPRE_IJVectorGetObject,jac->interior->ij,(void**)(&interior)); 340be14dc20SKerry Key PetscCallExternal(HYPRE_AMSSetInteriorNodes,jac->hsolver,interior); 341be14dc20SKerry Key } else { 342be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 343be14dc20SKerry Key } 3445ac14e1cSStefano Zampini } 3456bf688a0SCe Qin if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) { 3466bf688a0SCe Qin PetscInt i; 3476bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3486bf688a0SCe Qin if (jac->ND_PiFull) { 3496bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->ND_PiFull->data); 350792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsrfull)); 3516bf688a0SCe Qin } else { 3526bf688a0SCe Qin nd_parcsrfull = NULL; 3536bf688a0SCe Qin } 3546bf688a0SCe Qin for (i=0;i<3;++i) { 3556bf688a0SCe Qin if (jac->ND_Pi[i]) { 3566bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data); 357792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i])); 3586bf688a0SCe Qin } else { 3596bf688a0SCe Qin nd_parcsr[i] = NULL; 3606bf688a0SCe Qin } 3616bf688a0SCe Qin } 362792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetInterpolations,jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]); 3636bf688a0SCe Qin } 3644cb006feSStefano Zampini } 365863406b8SStefano Zampini /* special case for ADS */ 366863406b8SStefano Zampini if (jac->setup == HYPRE_ADSSetup) { 3675ac14e1cSStefano Zampini Mat_HYPRE *hm; 3685ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 3696bf688a0SCe 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])))) { 3706bf688a0SCe Qin SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations"); 3716bf688a0SCe Qin } 3727827d75bSBarry Smith 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"); 3735f80ce2aSJacob Faibussowitsch PetscCheck(jac->G,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3745f80ce2aSJacob Faibussowitsch PetscCheck(jac->C,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient"); 3755ac14e1cSStefano Zampini if (jac->coords[0]) { 3765ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3775ac14e1cSStefano Zampini coords[0] = NULL; 3785ac14e1cSStefano Zampini coords[1] = NULL; 3795ac14e1cSStefano Zampini coords[2] = NULL; 380792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0])); 381792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1])); 382792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2])); 383792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]); 3845ac14e1cSStefano Zampini } 3855ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->G->data); 386792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 387792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteGradient,jac->hsolver,parcsr); 3885ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->C->data); 389792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 390792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteCurl,jac->hsolver,parcsr); 3916bf688a0SCe Qin if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 3926bf688a0SCe Qin PetscInt i; 3936bf688a0SCe Qin HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3]; 3946bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3956bf688a0SCe Qin if (jac->RT_PiFull) { 3966bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->RT_PiFull->data); 397792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&rt_parcsrfull)); 3986bf688a0SCe Qin } else { 3996bf688a0SCe Qin rt_parcsrfull = NULL; 4006bf688a0SCe Qin } 4016bf688a0SCe Qin for (i=0;i<3;++i) { 4026bf688a0SCe Qin if (jac->RT_Pi[i]) { 4036bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data); 404792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&rt_parcsr[i])); 4056bf688a0SCe Qin } else { 4066bf688a0SCe Qin rt_parcsr[i] = NULL; 4076bf688a0SCe Qin } 4086bf688a0SCe Qin } 4096bf688a0SCe Qin if (jac->ND_PiFull) { 4106bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->ND_PiFull->data); 411792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsrfull)); 4126bf688a0SCe Qin } else { 4136bf688a0SCe Qin nd_parcsrfull = NULL; 4146bf688a0SCe Qin } 4156bf688a0SCe Qin for (i=0;i<3;++i) { 4166bf688a0SCe Qin if (jac->ND_Pi[i]) { 4176bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data); 418792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i])); 4196bf688a0SCe Qin } else { 4206bf688a0SCe Qin nd_parcsr[i] = NULL; 4216bf688a0SCe Qin } 4226bf688a0SCe Qin } 423792fecdfSBarry 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]); 4246bf688a0SCe Qin } 425863406b8SStefano Zampini } 426792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat); 427792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&bv); 428792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&xv); 429792fecdfSBarry Smith PetscCallExternal(jac->setup,jac->hsolver,hmat,bv,xv); 43016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 43116d9e3a6SLisandro Dalcin } 43216d9e3a6SLisandro Dalcin 43316d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x) 43416d9e3a6SLisandro Dalcin { 43516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 43649a781f5SStefano Zampini Mat_HYPRE *hjac = (Mat_HYPRE*)(jac->hpmat->data); 43716d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 43816d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 43916d9e3a6SLisandro Dalcin 44016d9e3a6SLisandro Dalcin PetscFunctionBegin; 4419566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 4429566063dSJacob Faibussowitsch if (!jac->applyrichardson) PetscCall(VecSet(x,0.0)); 4439566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b,b)); 4449566063dSJacob Faibussowitsch if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x,x)); 4459566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x,x)); 446792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat); 447792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv); 448792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv); 449e77caa6dSBarry Smith PetscStackCallExternalVoid("Hypre solve",do { 4505f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv); 4515f80ce2aSJacob Faibussowitsch if (hierr) { 4525f80ce2aSJacob Faibussowitsch PetscCheck(hierr == HYPRE_ERROR_CONV,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",(int)hierr); 4535f80ce2aSJacob Faibussowitsch hypre__global_error = 0; 4545f80ce2aSJacob Faibussowitsch } 4555f80ce2aSJacob Faibussowitsch } while (0)); 45616d9e3a6SLisandro Dalcin 45723df4f25SStefano Zampini if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) { 458792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSProjectOutGradients,jac->hsolver,jxv); 45921df291bSStefano Zampini } 4609566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 4619566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 46216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 46316d9e3a6SLisandro Dalcin } 46416d9e3a6SLisandro Dalcin 4658695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc) 4668695de01SBarry Smith { 4678695de01SBarry Smith PC_HYPRE *jac = (PC_HYPRE*)pc->data; 4688695de01SBarry Smith 4698695de01SBarry Smith PetscFunctionBegin; 4709566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 4719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 4729566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 4739566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 4749566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 4759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 4769566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[0])); 4779566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[1])); 4789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[2])); 4799566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 4809566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[0])); 4819566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[1])); 4829566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[2])); 4839566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 4849566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 4859566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 4869566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 4879566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 4889566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 489be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 4909566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 4915ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 492be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 4935ac14e1cSStefano Zampini jac->dim = 0; 4948695de01SBarry Smith PetscFunctionReturn(0); 4958695de01SBarry Smith } 4968695de01SBarry Smith 49716d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc) 49816d9e3a6SLisandro Dalcin { 49916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 50016d9e3a6SLisandro Dalcin 50116d9e3a6SLisandro Dalcin PetscFunctionBegin; 5029566063dSJacob Faibussowitsch PetscCall(PCReset_HYPRE(pc)); 503792fecdfSBarry Smith if (jac->destroy) PetscCallExternal(jac->destroy,jac->hsolver); 5049566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 505db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 5069566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->spgemm_type)); 507db6f9c32SMark Adams #endif 5089566063dSJacob Faibussowitsch if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre)); 5099566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 51016d9e3a6SLisandro Dalcin 5119566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc,0)); 5129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL)); 5139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL)); 5149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL)); 5159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL)); 5169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL)); 5179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL)); 5189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL)); 5192e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",NULL)); 520be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREAMSSetInteriorNodes_C",NULL)); 5219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL)); 5229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL)); 5239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",NULL)); 5249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",NULL)); 5252e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL)); 52616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 52716d9e3a6SLisandro Dalcin } 52816d9e3a6SLisandro Dalcin 52916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 5304416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc) 53116d9e3a6SLisandro Dalcin { 53216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 533ace3abfcSBarry Smith PetscBool flag; 53416d9e3a6SLisandro Dalcin 53516d9e3a6SLisandro Dalcin PetscFunctionBegin; 536d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE Pilut Options"); 5379566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag)); 538792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetMaxIter,jac->hsolver,jac->maxiter); 5399566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag)); 540792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetDropTolerance,jac->hsolver,jac->tol); 5419566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag)); 542792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetFactorRowSize,jac->hsolver,jac->factorrowsize); 543d0609cedSBarry Smith PetscOptionsHeadEnd(); 54416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 54516d9e3a6SLisandro Dalcin } 54616d9e3a6SLisandro Dalcin 54716d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer) 54816d9e3a6SLisandro Dalcin { 54916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 550ace3abfcSBarry Smith PetscBool iascii; 55116d9e3a6SLisandro Dalcin 55216d9e3a6SLisandro Dalcin PetscFunctionBegin; 5539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 55416d9e3a6SLisandro Dalcin if (iascii) { 5559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE Pilut preconditioning\n")); 55616d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 55763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," maximum number of iterations %" PetscInt_FMT "\n",jac->maxiter)); 55816d9e3a6SLisandro Dalcin } else { 5599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," default maximum number of iterations \n")); 56016d9e3a6SLisandro Dalcin } 56116d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 5629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," drop tolerance %g\n",(double)jac->tol)); 56316d9e3a6SLisandro Dalcin } else { 5649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," default drop tolerance \n")); 56516d9e3a6SLisandro Dalcin } 56616d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 56763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," factor row size %" PetscInt_FMT "\n",jac->factorrowsize)); 56816d9e3a6SLisandro Dalcin } else { 5699566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," default factor row size \n")); 57016d9e3a6SLisandro Dalcin } 57116d9e3a6SLisandro Dalcin } 57216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 57316d9e3a6SLisandro Dalcin } 57416d9e3a6SLisandro Dalcin 57516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 576db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc) 577db966c6cSHong Zhang { 578db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE*)pc->data; 5798bf83915SBarry Smith PetscBool flag,eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE; 580db966c6cSHong Zhang 581db966c6cSHong Zhang PetscFunctionBegin; 582d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE Euclid Options"); 5839566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag)); 584792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_EuclidSetLevel,jac->hsolver,jac->eu_level); 5858bf83915SBarry Smith 5869566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_euclid_droptolerance","Drop tolerance for ILU(k) in Euclid","None",jac->eu_droptolerance,&jac->eu_droptolerance,&flag)); 5878bf83915SBarry Smith if (flag) { 5888bf83915SBarry Smith PetscMPIInt size; 5898bf83915SBarry Smith 5909566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size)); 5917827d75bSBarry Smith PetscCheck(size == 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance"); 592792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetILUT,jac->hsolver,jac->eu_droptolerance); 5938bf83915SBarry Smith } 5948bf83915SBarry Smith 5959566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj,&eu_bj,&flag)); 5968bf83915SBarry Smith if (flag) { 5978bf83915SBarry Smith jac->eu_bj = eu_bj ? 1 : 0; 598792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetBJ,jac->hsolver,jac->eu_bj); 5998bf83915SBarry Smith } 600d0609cedSBarry Smith PetscOptionsHeadEnd(); 601db966c6cSHong Zhang PetscFunctionReturn(0); 602db966c6cSHong Zhang } 603db966c6cSHong Zhang 604db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer) 605db966c6cSHong Zhang { 606db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE*)pc->data; 607db966c6cSHong Zhang PetscBool iascii; 608db966c6cSHong Zhang 609db966c6cSHong Zhang PetscFunctionBegin; 6109566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 611db966c6cSHong Zhang if (iascii) { 6129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE Euclid preconditioning\n")); 613db966c6cSHong Zhang if (jac->eu_level != PETSC_DEFAULT) { 61463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," factorization levels %" PetscInt_FMT "\n",jac->eu_level)); 615db966c6cSHong Zhang } else { 6169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," default factorization levels \n")); 617db966c6cSHong Zhang } 6189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," drop tolerance %g\n",(double)jac->eu_droptolerance)); 61963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," use Block-Jacobi? %" PetscInt_FMT "\n",jac->eu_bj)); 620db966c6cSHong Zhang } 621db966c6cSHong Zhang PetscFunctionReturn(0); 622db966c6cSHong Zhang } 623db966c6cSHong Zhang 624db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/ 62516d9e3a6SLisandro Dalcin 62616d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x) 62716d9e3a6SLisandro Dalcin { 62816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 62949a781f5SStefano Zampini Mat_HYPRE *hjac = (Mat_HYPRE*)(jac->hpmat->data); 63016d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 63116d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 63216d9e3a6SLisandro Dalcin 63316d9e3a6SLisandro Dalcin PetscFunctionBegin; 6349566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 6359566063dSJacob Faibussowitsch PetscCall(VecSet(x,0.0)); 6369566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->x,b)); 6379566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->b,x)); 63816d9e3a6SLisandro Dalcin 639792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat); 640792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv); 641792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv); 64216d9e3a6SLisandro Dalcin 643e77caa6dSBarry Smith PetscStackCallExternalVoid("Hypre Transpose solve",do { 6445f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv); 6455f80ce2aSJacob Faibussowitsch if (hierr) { 64616d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 6475f80ce2aSJacob Faibussowitsch PetscCheck(hierr == 1,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",(int)hierr); 6485f80ce2aSJacob Faibussowitsch hypre__global_error = 0; 6495f80ce2aSJacob Faibussowitsch } 6505f80ce2aSJacob Faibussowitsch } while (0)); 65116d9e3a6SLisandro Dalcin 6529566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 6539566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 65416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 65516d9e3a6SLisandro Dalcin } 65616d9e3a6SLisandro Dalcin 657db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc,const char name[]) 658db6f9c32SMark Adams { 659db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE*)pc->data; 660db6f9c32SMark Adams PetscBool flag; 661db6f9c32SMark Adams 662db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 663db6f9c32SMark Adams PetscFunctionBegin; 664db6f9c32SMark Adams if (jac->spgemm_type) { 6659566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->spgemm_type,name,&flag)); 66628b400f6SJacob Faibussowitsch PetscCheck(flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE SpGEMM (really we can)"); 667db6f9c32SMark Adams PetscFunctionReturn(0); 668db6f9c32SMark Adams } else { 6699566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->spgemm_type)); 670db6f9c32SMark Adams } 6719566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("cusparse",jac->spgemm_type,&flag)); 672db6f9c32SMark Adams if (flag) { 673792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse,1); 674db6f9c32SMark Adams PetscFunctionReturn(0); 675db6f9c32SMark Adams } 6769566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("hypre",jac->spgemm_type,&flag)); 677db6f9c32SMark Adams if (flag) { 678792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse,0); 679db6f9c32SMark Adams PetscFunctionReturn(0); 680db6f9c32SMark Adams } 681db6f9c32SMark Adams jac->spgemm_type = NULL; 68298921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE SpGEM type %s; Choices are cusparse, hypre",name); 683db6f9c32SMark Adams #endif 684db6f9c32SMark Adams } 685db6f9c32SMark Adams 686db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[]) 687db6f9c32SMark Adams { 688db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE*)pc->data; 689db6f9c32SMark Adams 690db6f9c32SMark Adams PetscFunctionBegin; 691db6f9c32SMark Adams PetscValidHeaderSpecific(pc,PC_CLASSID,1); 692db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 693db6f9c32SMark Adams *spgemm = jac->spgemm_type; 694db6f9c32SMark Adams #endif 695db6f9c32SMark Adams PetscFunctionReturn(0); 696db6f9c32SMark Adams } 697db6f9c32SMark Adams 69816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"","V","W"}; 6990f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"}; 70016d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"}; 70165de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 7026a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[] = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"}; 70365de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[] = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi", 70465de4495SJed Brown "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi", 70565de4495SJed Brown "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination", 7067b7fa87dSPierre Jolivet "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */, 70765de4495SJed Brown "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"}; 7080f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[] = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i", 709589dcaf0SStefano Zampini "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1", 710589dcaf0SStefano Zampini "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"}; 7114416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc) 71216d9e3a6SLisandro Dalcin { 71316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 71422e51d31SStefano Zampini PetscInt bs,n,indx,level; 715ace3abfcSBarry Smith PetscBool flg, tmp_truth; 71616d9e3a6SLisandro Dalcin double tmpdbl, twodbl[2]; 717589dcaf0SStefano Zampini const char *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"}; 718db6f9c32SMark Adams const char *PCHYPRESpgemmTypes[] = {"cusparse","hypre"}; 71916d9e3a6SLisandro Dalcin 72016d9e3a6SLisandro Dalcin PetscFunctionBegin; 721d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE BoomerAMG Options"); 7229566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg)); 72316d9e3a6SLisandro Dalcin if (flg) { 7244336a9eeSBarry Smith jac->cycletype = indx+1; 725792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype); 72616d9e3a6SLisandro Dalcin } 7279566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg)); 72816d9e3a6SLisandro Dalcin if (flg) { 72963a3b9bcSJacob Faibussowitsch PetscCheck(jac->maxlevels >= 2,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %" PetscInt_FMT " must be at least two",jac->maxlevels); 730792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels); 73116d9e3a6SLisandro Dalcin } 7329566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg)); 73316d9e3a6SLisandro Dalcin if (flg) { 73463a3b9bcSJacob Faibussowitsch PetscCheck(jac->maxiter >= 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %" PetscInt_FMT " must be at least one",jac->maxiter); 735792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter); 73616d9e3a6SLisandro Dalcin } 7379566063dSJacob 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)); 73816d9e3a6SLisandro Dalcin if (flg) { 73908401ef6SPierre 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); 740792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol); 74116d9e3a6SLisandro Dalcin } 74222e51d31SStefano Zampini bs = 1; 74322e51d31SStefano Zampini if (pc->pmat) { 7449566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat,&bs)); 74522e51d31SStefano Zampini } 7469566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg)); 74722e51d31SStefano Zampini if (flg) { 748792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs); 74922e51d31SStefano Zampini } 75016d9e3a6SLisandro Dalcin 7519566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg)); 75216d9e3a6SLisandro Dalcin if (flg) { 75308401ef6SPierre 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); 754792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor); 75516d9e3a6SLisandro Dalcin } 75616d9e3a6SLisandro Dalcin 7579566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_P_max","Max elements per row for interpolation operator (0=unlimited)","None",jac->pmax,&jac->pmax,&flg)); 7580f1074feSSatish Balay if (flg) { 75963a3b9bcSJacob 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); 760792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax); 7610f1074feSSatish Balay } 7620f1074feSSatish Balay 7639566063dSJacob 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)); 764792fecdfSBarry Smith if (flg) PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl); 7650f1074feSSatish Balay 7669566063dSJacob 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)); 7670f1074feSSatish Balay if (flg) { 76863a3b9bcSJacob 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); 769792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths); 7700f1074feSSatish Balay } 7710f1074feSSatish Balay 7729566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg)); 77316d9e3a6SLisandro Dalcin if (flg) { 77408401ef6SPierre 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); 775792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold); 77616d9e3a6SLisandro Dalcin } 7779566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg)); 77816d9e3a6SLisandro Dalcin if (flg) { 77908401ef6SPierre 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); 78008401ef6SPierre 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); 781792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum); 78216d9e3a6SLisandro Dalcin } 78316d9e3a6SLisandro Dalcin 78416d9e3a6SLisandro Dalcin /* Grid sweeps */ 7859566063dSJacob 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)); 78616d9e3a6SLisandro Dalcin if (flg) { 787792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver,indx); 78816d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 78916d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 7900f1074feSSatish Balay jac->gridsweeps[1] = indx; 7910f1074feSSatish Balay /*defaults coarse to 1 */ 7920f1074feSSatish Balay jac->gridsweeps[2] = 1; 79316d9e3a6SLisandro Dalcin } 7949566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen","Use a nodal based coarsening 1-6","HYPRE_BoomerAMGSetNodal",jac->nodal_coarsening,&jac->nodal_coarsening,&flg)); 7955272c319SBarry Smith if (flg) { 796792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNodal,jac->hsolver,jac->nodal_coarsening); 7975272c319SBarry Smith } 7989566063dSJacob 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)); 79922e51d31SStefano Zampini if (flg) { 800792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNodalDiag,jac->hsolver,jac->nodal_coarsening_diag); 80122e51d31SStefano Zampini } 8029566063dSJacob 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)); 8035272c319SBarry Smith if (flg) { 804792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVecVariant,jac->hsolver,jac->vec_interp_variant); 8055272c319SBarry Smith } 8069566063dSJacob 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)); 80722e51d31SStefano Zampini if (flg) { 808792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVecQMax,jac->hsolver,jac->vec_interp_qmax); 80922e51d31SStefano Zampini } 8109566063dSJacob 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)); 81122e51d31SStefano Zampini if (flg) { 812792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothInterpVectors,jac->hsolver,jac->vec_interp_smooth); 81322e51d31SStefano Zampini } 8149566063dSJacob 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)); 81522e51d31SStefano Zampini if (flg) { 816792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpRefine,jac->hsolver,jac->interp_refine); 81722e51d31SStefano Zampini } 8189566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg)); 81916d9e3a6SLisandro Dalcin if (flg) { 820792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 1); 8210f1074feSSatish Balay jac->gridsweeps[0] = indx; 82216d9e3a6SLisandro Dalcin } 8239566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg)); 82416d9e3a6SLisandro Dalcin if (flg) { 825792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 2); 8260f1074feSSatish Balay jac->gridsweeps[1] = indx; 82716d9e3a6SLisandro Dalcin } 8289566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg)); 82916d9e3a6SLisandro Dalcin if (flg) { 830792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 3); 8310f1074feSSatish Balay jac->gridsweeps[2] = indx; 83216d9e3a6SLisandro Dalcin } 83316d9e3a6SLisandro Dalcin 8346a251517SEike Mueller /* Smooth type */ 835dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg)); 8366a251517SEike Mueller if (flg) { 8376a251517SEike Mueller jac->smoothtype = indx; 838792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,indx+6); 8398131ecf7SEike Mueller jac->smoothnumlevels = 25; 840792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,25); 8418131ecf7SEike Mueller } 8428131ecf7SEike Mueller 8438131ecf7SEike Mueller /* Number of smoothing levels */ 8449566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels","Number of levels on which more complex smoothers are used","None",25,&indx,&flg)); 8458131ecf7SEike Mueller if (flg && (jac->smoothtype != -1)) { 8468131ecf7SEike Mueller jac->smoothnumlevels = indx; 847792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,indx); 8486a251517SEike Mueller } 8496a251517SEike Mueller 8501810e44eSEike Mueller /* Number of levels for ILU(k) for Euclid */ 8519566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg)); 8521810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8531810e44eSEike Mueller jac->eu_level = indx; 854792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,indx); 8551810e44eSEike Mueller } 8561810e44eSEike Mueller 8571810e44eSEike Mueller /* Filter for ILU(k) for Euclid */ 8581810e44eSEike Mueller double droptolerance; 8599566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg)); 8601810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8611810e44eSEike Mueller jac->eu_droptolerance = droptolerance; 862792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,droptolerance); 8631810e44eSEike Mueller } 8641810e44eSEike Mueller 8651810e44eSEike Mueller /* Use Block Jacobi ILUT for Euclid */ 8669566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg)); 8671810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8681810e44eSEike Mueller jac->eu_bj = tmp_truth; 869792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuBJ,jac->hsolver,jac->eu_bj); 8701810e44eSEike Mueller } 8711810e44eSEike Mueller 87216d9e3a6SLisandro Dalcin /* Relax type */ 873dd39110bSPierre 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)); 87416d9e3a6SLisandro Dalcin if (flg) { 8750f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 876792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, indx); 8770f1074feSSatish Balay /* by default, coarse type set to 9 */ 8780f1074feSSatish Balay jac->relaxtype[2] = 9; 879792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, 9, 3); 88016d9e3a6SLisandro Dalcin } 881dd39110bSPierre 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)); 88216d9e3a6SLisandro Dalcin if (flg) { 88316d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 884792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 1); 88516d9e3a6SLisandro Dalcin } 886dd39110bSPierre 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)); 88716d9e3a6SLisandro Dalcin if (flg) { 8880f1074feSSatish Balay jac->relaxtype[1] = indx; 889792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 2); 89016d9e3a6SLisandro Dalcin } 891dd39110bSPierre 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)); 89216d9e3a6SLisandro Dalcin if (flg) { 8930f1074feSSatish Balay jac->relaxtype[2] = indx; 894792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 3); 89516d9e3a6SLisandro Dalcin } 89616d9e3a6SLisandro Dalcin 89716d9e3a6SLisandro Dalcin /* Relaxation Weight */ 8989566063dSJacob 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)); 89916d9e3a6SLisandro Dalcin if (flg) { 900792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxWt,jac->hsolver,tmpdbl); 90116d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 90216d9e3a6SLisandro Dalcin } 90316d9e3a6SLisandro Dalcin 90416d9e3a6SLisandro Dalcin n = 2; 90516d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 9069566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level","Set the relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg)); 90716d9e3a6SLisandro Dalcin if (flg) { 90816d9e3a6SLisandro Dalcin if (n == 2) { 90916d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 910792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelRelaxWt,jac->hsolver,twodbl[0],indx); 91163a3b9bcSJacob Faibussowitsch } else SETERRQ(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); 91216d9e3a6SLisandro Dalcin } 91316d9e3a6SLisandro Dalcin 91416d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 9159566063dSJacob 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)); 91616d9e3a6SLisandro Dalcin if (flg) { 917792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOuterWt,jac->hsolver, tmpdbl); 91816d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 91916d9e3a6SLisandro Dalcin } 92016d9e3a6SLisandro Dalcin 92116d9e3a6SLisandro Dalcin n = 2; 92216d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 9239566063dSJacob 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)); 92416d9e3a6SLisandro Dalcin if (flg) { 92516d9e3a6SLisandro Dalcin if (n == 2) { 92616d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 927792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelOuterWt,jac->hsolver, twodbl[0], indx); 92863a3b9bcSJacob Faibussowitsch } else SETERRQ(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); 92916d9e3a6SLisandro Dalcin } 93016d9e3a6SLisandro Dalcin 93116d9e3a6SLisandro Dalcin /* the Relax Order */ 9329566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg)); 93316d9e3a6SLisandro Dalcin 9348afaa268SBarry Smith if (flg && tmp_truth) { 93516d9e3a6SLisandro Dalcin jac->relaxorder = 0; 936792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder); 93716d9e3a6SLisandro Dalcin } 938dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg)); 93916d9e3a6SLisandro Dalcin if (flg) { 94016d9e3a6SLisandro Dalcin jac->measuretype = indx; 941792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype); 94216d9e3a6SLisandro Dalcin } 9430f1074feSSatish Balay /* update list length 3/07 */ 944dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg)); 94516d9e3a6SLisandro Dalcin if (flg) { 94616d9e3a6SLisandro Dalcin jac->coarsentype = indx; 947792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype); 94816d9e3a6SLisandro Dalcin } 9490f1074feSSatish Balay 9509566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg)); 951589dcaf0SStefano Zampini if (flg) { 952792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc); 953589dcaf0SStefano Zampini } 9549566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg)); 955589dcaf0SStefano Zampini if (flg) { 956792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc); 957589dcaf0SStefano Zampini } 958db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 959db6f9c32SMark Adams // global parameter but is closely associated with BoomerAMG 960dd39110bSPierre 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)); 961db6f9c32SMark Adams if (!flg) indx = 0; 9629566063dSJacob Faibussowitsch PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc,PCHYPRESpgemmTypes[indx])); 963db6f9c32SMark Adams #endif 964589dcaf0SStefano Zampini /* AIR */ 965589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0) 9669566063dSJacob 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)); 967792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype); 968589dcaf0SStefano Zampini if (jac->Rtype) { 969589dcaf0SStefano 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 */ 970589dcaf0SStefano Zampini 9719566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR","Threshold for R","None",jac->Rstrongthreshold,&jac->Rstrongthreshold,NULL)); 972792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold); 973589dcaf0SStefano Zampini 9749566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR","Filter threshold for R","None",jac->Rfilterthreshold,&jac->Rfilterthreshold,NULL)); 975792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold); 976589dcaf0SStefano Zampini 9779566063dSJacob 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)); 978792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol); 979589dcaf0SStefano Zampini 9809566063dSJacob 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)); 981792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype); 982589dcaf0SStefano Zampini } 983589dcaf0SStefano Zampini #endif 984589dcaf0SStefano Zampini 985ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9,9,9) 98663a3b9bcSJacob 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); 987ecae95adSPierre Jolivet #endif 988ecae95adSPierre Jolivet 9890f1074feSSatish Balay /* new 3/07 */ 990dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg)); 991589dcaf0SStefano Zampini if (flg || jac->Rtype) { 992589dcaf0SStefano Zampini if (flg) jac->interptype = indx; 993792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype); 9940f1074feSSatish Balay } 9950f1074feSSatish Balay 9969566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg)); 99716d9e3a6SLisandro Dalcin if (flg) { 998b96a4a96SBarry Smith level = 3; 9999566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL)); 10002fa5cd67SKarl Rupp 1001b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1002792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel,jac->hsolver,level); 10032ae77aedSBarry Smith } 10042ae77aedSBarry Smith 10059566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg)); 10062ae77aedSBarry Smith if (flg) { 1007b96a4a96SBarry Smith level = 3; 10089566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL)); 10092fa5cd67SKarl Rupp 1010b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1011792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDebugFlag,jac->hsolver,level); 101216d9e3a6SLisandro Dalcin } 10138f87f92bSBarry Smith 10149566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg)); 10158f87f92bSBarry Smith if (flg && tmp_truth) { 10168f87f92bSBarry Smith PetscInt tmp_int; 10179566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg)); 10188f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 1019792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,6); 1020792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDomainType,jac->hsolver,1); 1021792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOverlap,jac->hsolver,0); 1022792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,jac->nodal_relax_levels); 10238f87f92bSBarry Smith } 10248f87f92bSBarry Smith 10259566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL)); 1026792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0); 1027589dcaf0SStefano Zampini 1028589dcaf0SStefano Zampini /* options for ParaSails solvers */ 1029dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,PETSC_STATIC_ARRAY_LENGTH(symtlist),symtlist[0],&indx,&flg)); 1030589dcaf0SStefano Zampini if (flg) { 1031589dcaf0SStefano Zampini jac->symt = indx; 1032792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSym,jac->hsolver,jac->symt); 1033589dcaf0SStefano Zampini } 1034589dcaf0SStefano Zampini 1035d0609cedSBarry Smith PetscOptionsHeadEnd(); 103616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 103716d9e3a6SLisandro Dalcin } 103816d9e3a6SLisandro Dalcin 1039ace3abfcSBarry Smith 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) 104016d9e3a6SLisandro Dalcin { 104116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 10422cf14000SStefano Zampini HYPRE_Int oits; 104316d9e3a6SLisandro Dalcin 104416d9e3a6SLisandro Dalcin PetscFunctionBegin; 10459566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 1046792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,its*jac->maxiter); 1047792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,rtol); 104816d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 10499566063dSJacob Faibussowitsch PetscCall(PCApply_HYPRE(pc,b,y)); 105016d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 1051792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGGetNumIterations,jac->hsolver,&oits); 10524d0a8057SBarry Smith *outits = oits; 10534d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 10544d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1055792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol); 1056792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter); 105716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 105816d9e3a6SLisandro Dalcin } 105916d9e3a6SLisandro Dalcin 106016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer) 106116d9e3a6SLisandro Dalcin { 106216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1063ace3abfcSBarry Smith PetscBool iascii; 106416d9e3a6SLisandro Dalcin 106516d9e3a6SLisandro Dalcin PetscFunctionBegin; 10669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 106716d9e3a6SLisandro Dalcin if (iascii) { 10689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG preconditioning\n")); 10699566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype])); 107063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Maximum number of levels %" PetscInt_FMT "\n",jac->maxlevels)); 107163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Maximum number of iterations PER hypre call %" PetscInt_FMT "\n",jac->maxiter)); 10729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Convergence tolerance PER hypre call %g\n",(double)jac->tol)); 10739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Threshold for strong coupling %g\n",(double)jac->strongthreshold)); 10749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Interpolation truncation factor %g\n",(double)jac->truncfactor)); 107563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Interpolation: max elements per row %" PetscInt_FMT "\n",jac->pmax)); 107622e51d31SStefano Zampini if (jac->interp_refine) { 107763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n",jac->interp_refine)); 107822e51d31SStefano Zampini } 107963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Number of levels of aggressive coarsening %" PetscInt_FMT "\n",jac->agg_nl)); 108063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Number of paths for aggressive coarsening %" PetscInt_FMT "\n",jac->agg_num_paths)); 10810f1074feSSatish Balay 10829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Maximum row sums %g\n",(double)jac->maxrowsum)); 108316d9e3a6SLisandro Dalcin 108463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Sweeps down %" PetscInt_FMT "\n",jac->gridsweeps[0])); 108563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Sweeps up %" PetscInt_FMT "\n",jac->gridsweeps[1])); 108663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Sweeps on coarse %" PetscInt_FMT "\n",jac->gridsweeps[2])); 108716d9e3a6SLisandro Dalcin 10889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Relax down %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]])); 10899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Relax up %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]])); 10909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Relax on coarse %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]])); 109116d9e3a6SLisandro Dalcin 10929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Relax weight (all) %g\n",(double)jac->relaxweight)); 10939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Outer relax weight (all) %g\n",(double)jac->outerrelaxweight)); 109416d9e3a6SLisandro Dalcin 109516d9e3a6SLisandro Dalcin if (jac->relaxorder) { 10969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Using CF-relaxation\n")); 109716d9e3a6SLisandro Dalcin } else { 10989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Not using CF-relaxation\n")); 109916d9e3a6SLisandro Dalcin } 11006a251517SEike Mueller if (jac->smoothtype!=-1) { 11019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Smooth type %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype])); 110263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Smooth num levels %" PetscInt_FMT "\n",jac->smoothnumlevels)); 11037e352d70SEike Mueller } else { 11049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Not using more complex smoothers.\n")); 11051810e44eSEike Mueller } 11061810e44eSEike Mueller if (jac->smoothtype==3) { 110763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Euclid ILU(k) levels %" PetscInt_FMT "\n",jac->eu_level)); 11089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance)); 110963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n",jac->eu_bj)); 11106a251517SEike Mueller } 11119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Measure type %s\n",HYPREBoomerAMGMeasureType[jac->measuretype])); 11129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Coarsen type %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype])); 11139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Interpolation type %s\n",jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt")); 11145272c319SBarry Smith if (jac->nodal_coarsening) { 111563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n",jac->nodal_coarsening)); 11165272c319SBarry Smith } 11175272c319SBarry Smith if (jac->vec_interp_variant) { 111863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n",jac->vec_interp_variant)); 111963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n",jac->vec_interp_qmax)); 11209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth)); 11218f87f92bSBarry Smith } 11228f87f92bSBarry Smith if (jac->nodal_relax) { 112363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n",jac->nodal_relax_levels)); 11248f87f92bSBarry Smith } 1125db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 11269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," SpGEMM type %s\n",jac->spgemm_type)); 1127db6f9c32SMark Adams #endif 1128589dcaf0SStefano Zampini /* AIR */ 1129589dcaf0SStefano Zampini if (jac->Rtype) { 113063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Using approximate ideal restriction type %" PetscInt_FMT "\n",jac->Rtype)); 11319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Threshold for R %g\n",(double)jac->Rstrongthreshold)); 11329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Filter for R %g\n",(double)jac->Rfilterthreshold)); 11339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," A drop tolerance %g\n",(double)jac->Adroptol)); 113463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," A drop type %" PetscInt_FMT "\n",jac->Adroptype)); 1135589dcaf0SStefano Zampini } 113616d9e3a6SLisandro Dalcin } 113716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 113816d9e3a6SLisandro Dalcin } 113916d9e3a6SLisandro Dalcin 114016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 11414416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc) 114216d9e3a6SLisandro Dalcin { 114316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 11444ddd07fcSJed Brown PetscInt indx; 1145ace3abfcSBarry Smith PetscBool flag; 114616d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"}; 114716d9e3a6SLisandro Dalcin 114816d9e3a6SLisandro Dalcin PetscFunctionBegin; 1149d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE ParaSails Options"); 11509566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0)); 11519566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag)); 1152792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels); 115316d9e3a6SLisandro Dalcin 11549566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag)); 1155792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter); 115616d9e3a6SLisandro Dalcin 11579566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag)); 1158792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal); 115916d9e3a6SLisandro Dalcin 11609566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag)); 1161792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging); 116216d9e3a6SLisandro Dalcin 11639566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag)); 1164792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse); 116516d9e3a6SLisandro Dalcin 1166dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,PETSC_STATIC_ARRAY_LENGTH(symtlist),symtlist[0],&indx,&flag)); 116716d9e3a6SLisandro Dalcin if (flag) { 116816d9e3a6SLisandro Dalcin jac->symt = indx; 1169792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt); 117016d9e3a6SLisandro Dalcin } 117116d9e3a6SLisandro Dalcin 1172d0609cedSBarry Smith PetscOptionsHeadEnd(); 117316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 117416d9e3a6SLisandro Dalcin } 117516d9e3a6SLisandro Dalcin 117616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer) 117716d9e3a6SLisandro Dalcin { 117816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1179ace3abfcSBarry Smith PetscBool iascii; 1180feb237baSPierre Jolivet const char *symt = 0; 118116d9e3a6SLisandro Dalcin 118216d9e3a6SLisandro Dalcin PetscFunctionBegin; 11839566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 118416d9e3a6SLisandro Dalcin if (iascii) { 11859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE ParaSails preconditioning\n")); 118663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," nlevels %" PetscInt_FMT "\n",jac->nlevels)); 11879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," threshold %g\n",(double)jac->threshold)); 11889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," filter %g\n",(double)jac->filter)); 11899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," load balance %g\n",(double)jac->loadbal)); 11909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," reuse nonzero structure %s\n",PetscBools[jac->ruse])); 11919566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," print info to screen %s\n",PetscBools[jac->logging])); 11922fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 11932fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 11942fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 119563a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT,jac->symt); 11969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," %s\n",symt)); 119716d9e3a6SLisandro Dalcin } 119816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 119916d9e3a6SLisandro Dalcin } 12004cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/ 12014416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc) 12024cb006feSStefano Zampini { 12034cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 12044cb006feSStefano Zampini PetscInt n; 12054cb006feSStefano Zampini PetscBool flag,flag2,flag3,flag4; 12064cb006feSStefano Zampini 12074cb006feSStefano Zampini PetscFunctionBegin; 1208d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE AMS Options"); 12099566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag)); 1210792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print); 12119566063dSJacob 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)); 1212792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter); 12139566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type","Cycle type for AMS multigrid","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag)); 1214792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type); 12159566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag)); 1216792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol); 12179566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag)); 12189566063dSJacob 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)); 12199566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3)); 12209566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4)); 12214cb006feSStefano Zampini if (flag || flag2 || flag3 || flag4) { 1222792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type, 1223863406b8SStefano Zampini jac->as_relax_times, 1224863406b8SStefano Zampini jac->as_relax_weight, 1225a74df02fSJacob Faibussowitsch jac->as_omega); 12264cb006feSStefano Zampini } 12279566063dSJacob 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)); 12284cb006feSStefano Zampini n = 5; 12299566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2)); 12304cb006feSStefano Zampini if (flag || flag2) { 1231792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1232863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1233863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 1234863406b8SStefano Zampini jac->as_amg_alpha_theta, 1235863406b8SStefano Zampini jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1236a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 12374cb006feSStefano Zampini } 12389566063dSJacob 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)); 12394cb006feSStefano Zampini n = 5; 12409566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->as_amg_beta_opts,&n,&flag2)); 12414cb006feSStefano Zampini if (flag || flag2) { 1242792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1243863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1244863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 1245863406b8SStefano Zampini jac->as_amg_beta_theta, 1246863406b8SStefano Zampini jac->as_amg_beta_opts[3], /* AMG interp_type */ 1247a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 12484cb006feSStefano Zampini } 12499566063dSJacob 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)); 125023df4f25SStefano Zampini if (flag) { /* override HYPRE's default only if the options is used */ 1251792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetProjectionFrequency,jac->hsolver,jac->ams_proj_freq); 125223df4f25SStefano Zampini } 1253d0609cedSBarry Smith PetscOptionsHeadEnd(); 12544cb006feSStefano Zampini PetscFunctionReturn(0); 12554cb006feSStefano Zampini } 12564cb006feSStefano Zampini 12574cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer) 12584cb006feSStefano Zampini { 12594cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 12604cb006feSStefano Zampini PetscBool iascii; 12614cb006feSStefano Zampini 12624cb006feSStefano Zampini PetscFunctionBegin; 12639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 12644cb006feSStefano Zampini if (iascii) { 12659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE AMS preconditioning\n")); 126663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace iterations per application %" PetscInt_FMT "\n",jac->as_max_iter)); 126763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace cycle type %" PetscInt_FMT "\n",jac->ams_cycle_type)); 126863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace iteration tolerance %g\n",(double)jac->as_tol)); 126963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother type %" PetscInt_FMT "\n",jac->as_relax_type)); 127063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," number of smoothing steps %" PetscInt_FMT "\n",jac->as_relax_times)); 127163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother weight %g\n",(double)jac->as_relax_weight)); 127263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother omega %g\n",(double)jac->as_omega)); 12734cb006feSStefano Zampini if (jac->alpha_Poisson) { 12749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," vector Poisson solver (passed in by user)\n")); 12754cb006feSStefano Zampini } else { 12769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," vector Poisson solver (computed) \n")); 12774cb006feSStefano Zampini } 127863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG coarsening type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[0])); 127963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[1])); 128063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG relaxation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[2])); 128163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG interpolation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[3])); 128263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[4])); 128363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG strength threshold %g\n",(double)jac->as_amg_alpha_theta)); 12844cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 12854cb006feSStefano Zampini if (jac->beta_Poisson) { 12869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," scalar Poisson solver (passed in by user)\n")); 12874cb006feSStefano Zampini } else { 12889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," scalar Poisson solver (computed) \n")); 12894cb006feSStefano Zampini } 129063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG coarsening type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[0])); 129163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_beta_opts[1])); 129263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG relaxation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[2])); 129363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG interpolation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[3])); 129463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_beta_opts[4])); 129563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG strength threshold %g\n",(double)jac->as_amg_beta_theta)); 129623df4f25SStefano Zampini if (jac->ams_beta_is_zero_part) { 129763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," compatible subspace projection frequency %" PetscInt_FMT " (-1 HYPRE uses default)\n",jac->ams_proj_freq)); 129823df4f25SStefano Zampini } 129923df4f25SStefano Zampini } else { 13009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," scalar Poisson solver not used (zero-conductivity everywhere) \n")); 13014cb006feSStefano Zampini } 13024cb006feSStefano Zampini } 13034cb006feSStefano Zampini PetscFunctionReturn(0); 13044cb006feSStefano Zampini } 13054cb006feSStefano Zampini 13064416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc) 1307863406b8SStefano Zampini { 1308863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1309863406b8SStefano Zampini PetscInt n; 1310863406b8SStefano Zampini PetscBool flag,flag2,flag3,flag4; 1311863406b8SStefano Zampini 1312863406b8SStefano Zampini PetscFunctionBegin; 1313d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE ADS Options"); 13149566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag)); 1315792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print); 13169566063dSJacob 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)); 1317792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter); 13189566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type","Cycle type for ADS multigrid","None",jac->ads_cycle_type,&jac->ads_cycle_type,&flag)); 1319792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetCycleType,jac->hsolver,jac->ads_cycle_type); 13209566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag)); 1321792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol); 13229566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type","Relaxation type for ADS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag)); 13239566063dSJacob 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)); 13249566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight","Relaxation weight for ADS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3)); 13259566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4)); 1326863406b8SStefano Zampini if (flag || flag2 || flag3 || flag4) { 1327792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type, 1328863406b8SStefano Zampini jac->as_relax_times, 1329863406b8SStefano Zampini jac->as_relax_weight, 1330a74df02fSJacob Faibussowitsch jac->as_omega); 1331863406b8SStefano Zampini } 13329566063dSJacob 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)); 1333863406b8SStefano Zampini n = 5; 13349566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options","AMG options for AMS solver inside ADS","None",jac->as_amg_alpha_opts,&n,&flag2)); 13359566063dSJacob 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)); 1336863406b8SStefano Zampini if (flag || flag2 || flag3) { 1337792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type, /* AMS cycle type */ 1338863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1339863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1340863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 1341863406b8SStefano Zampini jac->as_amg_alpha_theta, 1342863406b8SStefano Zampini jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1343a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 1344863406b8SStefano Zampini } 13459566063dSJacob 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)); 1346863406b8SStefano Zampini n = 5; 13479566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options","AMG options for vector AMG solver inside ADS","None",jac->as_amg_beta_opts,&n,&flag2)); 1348863406b8SStefano Zampini if (flag || flag2) { 1349792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1350863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1351863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 1352863406b8SStefano Zampini jac->as_amg_beta_theta, 1353863406b8SStefano Zampini jac->as_amg_beta_opts[3], /* AMG interp_type */ 1354a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 1355863406b8SStefano Zampini } 1356d0609cedSBarry Smith PetscOptionsHeadEnd(); 1357863406b8SStefano Zampini PetscFunctionReturn(0); 1358863406b8SStefano Zampini } 1359863406b8SStefano Zampini 1360863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer) 1361863406b8SStefano Zampini { 1362863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1363863406b8SStefano Zampini PetscBool iascii; 1364863406b8SStefano Zampini 1365863406b8SStefano Zampini PetscFunctionBegin; 13669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 1367863406b8SStefano Zampini if (iascii) { 13689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE ADS preconditioning\n")); 136963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace iterations per application %" PetscInt_FMT "\n",jac->as_max_iter)); 137063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace cycle type %" PetscInt_FMT "\n",jac->ads_cycle_type)); 137163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace iteration tolerance %g\n",(double)jac->as_tol)); 137263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother type %" PetscInt_FMT "\n",jac->as_relax_type)); 137363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," number of smoothing steps %" PetscInt_FMT "\n",jac->as_relax_times)); 137463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother weight %g\n",(double)jac->as_relax_weight)); 137563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother omega %g\n",(double)jac->as_omega)); 13769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," AMS solver using boomerAMG\n")); 137763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace cycle type %" PetscInt_FMT "\n",jac->ams_cycle_type)); 137863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," coarsening type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[0])); 137963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[1])); 138063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," relaxation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[2])); 138163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," interpolation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[3])); 138263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[4])); 138363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," strength threshold %g\n",(double)jac->as_amg_alpha_theta)); 13849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," vector Poisson solver using boomerAMG\n")); 138563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," coarsening type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[0])); 138663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_beta_opts[1])); 138763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," relaxation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[2])); 138863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," interpolation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[3])); 138963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_beta_opts[4])); 139063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," strength threshold %g\n",(double)jac->as_amg_beta_theta)); 1391863406b8SStefano Zampini } 1392863406b8SStefano Zampini PetscFunctionReturn(0); 1393863406b8SStefano Zampini } 1394863406b8SStefano Zampini 1395863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G) 13964cb006feSStefano Zampini { 13974cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 13985ac14e1cSStefano Zampini PetscBool ishypre; 13994cb006feSStefano Zampini 14004cb006feSStefano Zampini PetscFunctionBegin; 14019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre)); 14025ac14e1cSStefano Zampini if (ishypre) { 14039566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)G)); 14049566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 14055ac14e1cSStefano Zampini jac->G = G; 14065ac14e1cSStefano Zampini } else { 14079566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 14089566063dSJacob Faibussowitsch PetscCall(MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G)); 14095ac14e1cSStefano Zampini } 14104cb006feSStefano Zampini PetscFunctionReturn(0); 14114cb006feSStefano Zampini } 14124cb006feSStefano Zampini 14134cb006feSStefano Zampini /*@ 14144cb006feSStefano Zampini PCHYPRESetDiscreteGradient - Set discrete gradient matrix 14154cb006feSStefano Zampini 14164cb006feSStefano Zampini Collective on PC 14174cb006feSStefano Zampini 14184cb006feSStefano Zampini Input Parameters: 14194cb006feSStefano Zampini + pc - the preconditioning context 14204cb006feSStefano Zampini - G - the discrete gradient 14214cb006feSStefano Zampini 14224cb006feSStefano Zampini Level: intermediate 14234cb006feSStefano Zampini 142495452b02SPatrick Sanan Notes: 142595452b02SPatrick Sanan G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 1426147403d9SBarry Smith 1427863406b8SStefano 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 14284cb006feSStefano Zampini 1429db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteCurl()` 14304cb006feSStefano Zampini @*/ 14314cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 14324cb006feSStefano Zampini { 14334cb006feSStefano Zampini PetscFunctionBegin; 14344cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 14354cb006feSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 14364cb006feSStefano Zampini PetscCheckSameComm(pc,1,G,2); 1437cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G)); 14384cb006feSStefano Zampini PetscFunctionReturn(0); 14394cb006feSStefano Zampini } 14404cb006feSStefano Zampini 1441863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C) 1442863406b8SStefano Zampini { 1443863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 14445ac14e1cSStefano Zampini PetscBool ishypre; 1445863406b8SStefano Zampini 1446863406b8SStefano Zampini PetscFunctionBegin; 14479566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre)); 14485ac14e1cSStefano Zampini if (ishypre) { 14499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)C)); 14509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 14515ac14e1cSStefano Zampini jac->C = C; 14525ac14e1cSStefano Zampini } else { 14539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 14549566063dSJacob Faibussowitsch PetscCall(MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C)); 14555ac14e1cSStefano Zampini } 1456863406b8SStefano Zampini PetscFunctionReturn(0); 1457863406b8SStefano Zampini } 1458863406b8SStefano Zampini 1459863406b8SStefano Zampini /*@ 1460863406b8SStefano Zampini PCHYPRESetDiscreteCurl - Set discrete curl matrix 1461863406b8SStefano Zampini 1462863406b8SStefano Zampini Collective on PC 1463863406b8SStefano Zampini 1464863406b8SStefano Zampini Input Parameters: 1465863406b8SStefano Zampini + pc - the preconditioning context 1466863406b8SStefano Zampini - C - the discrete curl 1467863406b8SStefano Zampini 1468863406b8SStefano Zampini Level: intermediate 1469863406b8SStefano Zampini 147095452b02SPatrick Sanan Notes: 147195452b02SPatrick Sanan C should have as many rows as the number of faces and as many columns as the number of edges in the mesh 1472147403d9SBarry Smith 1473863406b8SStefano 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 1474863406b8SStefano Zampini 1475db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()` 1476863406b8SStefano Zampini @*/ 1477863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C) 1478863406b8SStefano Zampini { 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)); 1484863406b8SStefano Zampini PetscFunctionReturn(0); 1485863406b8SStefano Zampini } 1486863406b8SStefano Zampini 14876bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 14886bf688a0SCe Qin { 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 15476bf688a0SCe Qin PetscFunctionReturn(0); 15486bf688a0SCe Qin } 15496bf688a0SCe Qin 15506bf688a0SCe Qin /*@ 15516bf688a0SCe Qin PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner 15526bf688a0SCe Qin 15536bf688a0SCe Qin Collective on PC 15546bf688a0SCe Qin 15556bf688a0SCe Qin Input Parameters: 15566bf688a0SCe Qin + pc - the preconditioning context 15576bf688a0SCe Qin - dim - the dimension of the problem, only used in AMS 15586bf688a0SCe Qin - RT_PiFull - Raviart-Thomas interpolation matrix 15596bf688a0SCe Qin - RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix 15606bf688a0SCe Qin - ND_PiFull - Nedelec interpolation matrix 15616bf688a0SCe Qin - ND_Pi - x/y/z component of Nedelec interpolation matrix 15626bf688a0SCe Qin 156395452b02SPatrick Sanan Notes: 156495452b02SPatrick Sanan For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL. 1565147403d9SBarry Smith 15666bf688a0SCe Qin For ADS, both type of interpolation matrices are needed. 1567147403d9SBarry Smith 15686bf688a0SCe Qin Level: intermediate 15696bf688a0SCe Qin 15706bf688a0SCe Qin @*/ 15716bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 15726bf688a0SCe Qin { 15736bf688a0SCe Qin PetscInt i; 15746bf688a0SCe Qin 15756bf688a0SCe Qin PetscFunctionBegin; 15766bf688a0SCe Qin PetscValidHeaderSpecific(pc,PC_CLASSID,1); 15776bf688a0SCe Qin if (RT_PiFull) { 15786bf688a0SCe Qin PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3); 15796bf688a0SCe Qin PetscCheckSameComm(pc,1,RT_PiFull,3); 15806bf688a0SCe Qin } 15816bf688a0SCe Qin if (RT_Pi) { 15826bf688a0SCe Qin PetscValidPointer(RT_Pi,4); 15836bf688a0SCe Qin for (i=0;i<dim;++i) { 15846bf688a0SCe Qin if (RT_Pi[i]) { 15856bf688a0SCe Qin PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4); 15866bf688a0SCe Qin PetscCheckSameComm(pc,1,RT_Pi[i],4); 15876bf688a0SCe Qin } 15886bf688a0SCe Qin } 15896bf688a0SCe Qin } 15906bf688a0SCe Qin if (ND_PiFull) { 15916bf688a0SCe Qin PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5); 15926bf688a0SCe Qin PetscCheckSameComm(pc,1,ND_PiFull,5); 15936bf688a0SCe Qin } 15946bf688a0SCe Qin if (ND_Pi) { 15956bf688a0SCe Qin PetscValidPointer(ND_Pi,6); 15966bf688a0SCe Qin for (i=0;i<dim;++i) { 15976bf688a0SCe Qin if (ND_Pi[i]) { 15986bf688a0SCe Qin PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6); 15996bf688a0SCe Qin PetscCheckSameComm(pc,1,ND_Pi[i],6); 16006bf688a0SCe Qin } 16016bf688a0SCe Qin } 16026bf688a0SCe Qin } 1603cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi)); 16046bf688a0SCe Qin PetscFunctionReturn(0); 16056bf688a0SCe Qin } 16066bf688a0SCe Qin 16075ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha) 16084cb006feSStefano Zampini { 16094cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 16105ac14e1cSStefano Zampini PetscBool ishypre; 16114cb006feSStefano Zampini 16124cb006feSStefano Zampini PetscFunctionBegin; 16139566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre)); 16145ac14e1cSStefano Zampini if (ishypre) { 16155ac14e1cSStefano Zampini if (isalpha) { 16169566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 16179566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 16185ac14e1cSStefano Zampini jac->alpha_Poisson = A; 16195ac14e1cSStefano Zampini } else { 16205ac14e1cSStefano Zampini if (A) { 16219566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 16225ac14e1cSStefano Zampini } else { 16235ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 16245ac14e1cSStefano Zampini } 16259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16265ac14e1cSStefano Zampini jac->beta_Poisson = A; 16275ac14e1cSStefano Zampini } 16285ac14e1cSStefano Zampini } else { 16295ac14e1cSStefano Zampini if (isalpha) { 16309566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 16319566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson)); 16325ac14e1cSStefano Zampini } else { 16335ac14e1cSStefano Zampini if (A) { 16349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16359566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson)); 16365ac14e1cSStefano Zampini } else { 16379566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16385ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 16395ac14e1cSStefano Zampini } 16405ac14e1cSStefano Zampini } 16415ac14e1cSStefano Zampini } 16424cb006feSStefano Zampini PetscFunctionReturn(0); 16434cb006feSStefano Zampini } 16444cb006feSStefano Zampini 16454cb006feSStefano Zampini /*@ 16464cb006feSStefano Zampini PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix 16474cb006feSStefano Zampini 16484cb006feSStefano Zampini Collective on PC 16494cb006feSStefano Zampini 16504cb006feSStefano Zampini Input Parameters: 16514cb006feSStefano Zampini + pc - the preconditioning context 16524cb006feSStefano Zampini - A - the matrix 16534cb006feSStefano Zampini 16544cb006feSStefano Zampini Level: intermediate 16554cb006feSStefano Zampini 165695452b02SPatrick Sanan Notes: 165795452b02SPatrick Sanan A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 16584cb006feSStefano Zampini 1659db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()` 16604cb006feSStefano Zampini @*/ 16614cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 16624cb006feSStefano Zampini { 16634cb006feSStefano Zampini PetscFunctionBegin; 16644cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 16654cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 16664cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 1667cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE)); 16684cb006feSStefano Zampini PetscFunctionReturn(0); 16694cb006feSStefano Zampini } 16704cb006feSStefano Zampini 16714cb006feSStefano Zampini /*@ 16724cb006feSStefano Zampini PCHYPRESetBetaPoissonMatrix - Set Poisson matrix 16734cb006feSStefano Zampini 16744cb006feSStefano Zampini Collective on PC 16754cb006feSStefano Zampini 16764cb006feSStefano Zampini Input Parameters: 16774cb006feSStefano Zampini + pc - the preconditioning context 16784cb006feSStefano Zampini - A - the matrix 16794cb006feSStefano Zampini 16804cb006feSStefano Zampini Level: intermediate 16814cb006feSStefano Zampini 168295452b02SPatrick Sanan Notes: 168395452b02SPatrick Sanan A should be obtained by discretizing the Poisson problem with linear finite elements. 16844cb006feSStefano Zampini Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL. 16854cb006feSStefano Zampini 1686db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 16874cb006feSStefano Zampini @*/ 16884cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 16894cb006feSStefano Zampini { 16904cb006feSStefano Zampini PetscFunctionBegin; 16914cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 16924cb006feSStefano Zampini if (A) { 16934cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 16944cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 16954cb006feSStefano Zampini } 1696cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE)); 16974cb006feSStefano Zampini PetscFunctionReturn(0); 16984cb006feSStefano Zampini } 16994cb006feSStefano Zampini 17005ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo) 17014cb006feSStefano Zampini { 17024cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 17034cb006feSStefano Zampini 17044cb006feSStefano Zampini PetscFunctionBegin; 17054cb006feSStefano Zampini /* throw away any vector if already set */ 17069566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 17079566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 17089566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 17099566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(ozz->map,&jac->constants[0])); 17109566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(ozz,jac->constants[0])); 17119566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zoz->map,&jac->constants[1])); 17129566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zoz,jac->constants[1])); 17135ac14e1cSStefano Zampini jac->dim = 2; 17144cb006feSStefano Zampini if (zzo) { 17159566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zzo->map,&jac->constants[2])); 17169566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zzo,jac->constants[2])); 17175ac14e1cSStefano Zampini jac->dim++; 17184cb006feSStefano Zampini } 17194cb006feSStefano Zampini PetscFunctionReturn(0); 17204cb006feSStefano Zampini } 17214cb006feSStefano Zampini 17224cb006feSStefano Zampini /*@ 1723147403d9SBarry Smith PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis 17244cb006feSStefano Zampini 17254cb006feSStefano Zampini Collective on PC 17264cb006feSStefano Zampini 17274cb006feSStefano Zampini Input Parameters: 17284cb006feSStefano Zampini + pc - the preconditioning context 17294cb006feSStefano Zampini - ozz - vector representing (1,0,0) (or (1,0) in 2D) 17304cb006feSStefano Zampini - zoz - vector representing (0,1,0) (or (0,1) in 2D) 17314cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 17324cb006feSStefano Zampini 17334cb006feSStefano Zampini Level: intermediate 17344cb006feSStefano Zampini 17354cb006feSStefano Zampini @*/ 17364cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 17374cb006feSStefano Zampini { 17384cb006feSStefano Zampini PetscFunctionBegin; 17394cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 17404cb006feSStefano Zampini PetscValidHeaderSpecific(ozz,VEC_CLASSID,2); 17414cb006feSStefano Zampini PetscValidHeaderSpecific(zoz,VEC_CLASSID,3); 17424cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4); 17434cb006feSStefano Zampini PetscCheckSameComm(pc,1,ozz,2); 17444cb006feSStefano Zampini PetscCheckSameComm(pc,1,zoz,3); 17454cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc,1,zzo,4); 1746cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo)); 17474cb006feSStefano Zampini PetscFunctionReturn(0); 17484cb006feSStefano Zampini } 17494cb006feSStefano Zampini 1750be14dc20SKerry Key static PetscErrorCode PCHYPREAMSSetInteriorNodes_HYPRE(PC pc,Vec interior) 1751be14dc20SKerry Key { 1752be14dc20SKerry Key PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1753be14dc20SKerry Key 1754be14dc20SKerry Key PetscFunctionBegin; 1755be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 1756be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCreate(interior->map,&jac->interior)); 1757be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCopy(interior,jac->interior)); 1758be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_TRUE; 1759be14dc20SKerry Key PetscFunctionReturn(0); 1760be14dc20SKerry Key } 1761be14dc20SKerry Key 1762be14dc20SKerry Key /*@ 1763be14dc20SKerry Key PCHYPREAMSSetInteriorNodes - Set the list of interior nodes to a zero-conductivity region. 1764be14dc20SKerry Key 1765be14dc20SKerry Key Collective on PC 1766be14dc20SKerry Key 1767be14dc20SKerry Key Input Parameters: 1768be14dc20SKerry Key + pc - the preconditioning context 1769be14dc20SKerry Key - interior - vector. node is interior if its entry in the array is 1.0. 1770be14dc20SKerry Key 1771be14dc20SKerry Key Level: intermediate 1772be14dc20SKerry Key 1773be14dc20SKerry Key Note: 1774be14dc20SKerry Key This calls HYPRE_AMSSetInteriorNodes() 1775be14dc20SKerry Key .seealso: 1776be14dc20SKerry Key @*/ 1777be14dc20SKerry Key PetscErrorCode PCHYPREAMSSetInteriorNodes(PC pc, Vec interior) 1778be14dc20SKerry Key { 1779be14dc20SKerry Key PetscFunctionBegin; 1780be14dc20SKerry Key PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1781be14dc20SKerry Key PetscValidHeaderSpecific(interior,VEC_CLASSID,2); 1782be14dc20SKerry Key PetscCheckSameComm(pc,1,interior,2); 1783be14dc20SKerry Key PetscTryMethod(pc,"PCHYPREAMSSetInteriorNodes_C",(PC,Vec),(pc,interior)); 1784be14dc20SKerry Key PetscFunctionReturn(0); 1785be14dc20SKerry Key } 1786be14dc20SKerry Key 1787863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 17884cb006feSStefano Zampini { 17894cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 17904cb006feSStefano Zampini Vec tv; 17914cb006feSStefano Zampini PetscInt i; 17924cb006feSStefano Zampini 17934cb006feSStefano Zampini PetscFunctionBegin; 17944cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 17959566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 17969566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 17979566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 17985ac14e1cSStefano Zampini jac->dim = dim; 17995ac14e1cSStefano Zampini 18004cb006feSStefano Zampini /* compute IJ vector for coordinates */ 18019566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)pc),&tv)); 18029566063dSJacob Faibussowitsch PetscCall(VecSetType(tv,VECSTANDARD)); 18039566063dSJacob Faibussowitsch PetscCall(VecSetSizes(tv,nloc,PETSC_DECIDE)); 18044cb006feSStefano Zampini for (i=0;i<dim;i++) { 18054cb006feSStefano Zampini PetscScalar *array; 18064cb006feSStefano Zampini PetscInt j; 18074cb006feSStefano Zampini 18089566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(tv->map,&jac->coords[i])); 18099566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(tv,&array)); 18106ea7df73SStefano Zampini for (j=0;j<nloc;j++) array[j] = coords[j*dim+i]; 18119566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(tv,&array)); 18129566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(tv,jac->coords[i])); 18134cb006feSStefano Zampini } 18149566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tv)); 18154cb006feSStefano Zampini PetscFunctionReturn(0); 18164cb006feSStefano Zampini } 18174cb006feSStefano Zampini 181816d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/ 181916d9e3a6SLisandro Dalcin 1820f7a08781SBarry Smith static PetscErrorCode PCHYPREGetType_HYPRE(PC pc,const char *name[]) 182116d9e3a6SLisandro Dalcin { 182216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 182316d9e3a6SLisandro Dalcin 182416d9e3a6SLisandro Dalcin PetscFunctionBegin; 182516d9e3a6SLisandro Dalcin *name = jac->hypre_type; 182616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 182716d9e3a6SLisandro Dalcin } 182816d9e3a6SLisandro Dalcin 1829f7a08781SBarry Smith static PetscErrorCode PCHYPRESetType_HYPRE(PC pc,const char name[]) 183016d9e3a6SLisandro Dalcin { 183116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1832ace3abfcSBarry Smith PetscBool flag; 183316d9e3a6SLisandro Dalcin 183416d9e3a6SLisandro Dalcin PetscFunctionBegin; 183516d9e3a6SLisandro Dalcin if (jac->hypre_type) { 18369566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type,name,&flag)); 18375f80ce2aSJacob Faibussowitsch PetscCheck(flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set"); 183816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 183916d9e3a6SLisandro Dalcin } else { 18409566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->hypre_type)); 184116d9e3a6SLisandro Dalcin } 184216d9e3a6SLisandro Dalcin 184316d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 184416d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 184516d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 184616d9e3a6SLisandro Dalcin 18479566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("pilut",jac->hypre_type,&flag)); 184816d9e3a6SLisandro Dalcin if (flag) { 18499566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre)); 1850792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRPilutCreate,jac->comm_hypre,&jac->hsolver); 185116d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 185216d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 185316d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 185416d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 185516d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 185616d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 185716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 185816d9e3a6SLisandro Dalcin } 18599566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("euclid",jac->hypre_type,&flag)); 1860db966c6cSHong Zhang if (flag) { 18614e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 18624e3c431bSBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid does not support 64 bit indices"); 18638bf83915SBarry Smith #endif 18649566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre)); 1865792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidCreate,jac->comm_hypre,&jac->hsolver); 1866db966c6cSHong Zhang pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 1867db966c6cSHong Zhang pc->ops->view = PCView_HYPRE_Euclid; 1868db966c6cSHong Zhang jac->destroy = HYPRE_EuclidDestroy; 1869db966c6cSHong Zhang jac->setup = HYPRE_EuclidSetup; 1870db966c6cSHong Zhang jac->solve = HYPRE_EuclidSolve; 1871db966c6cSHong Zhang jac->factorrowsize = PETSC_DEFAULT; 1872db966c6cSHong Zhang jac->eu_level = PETSC_DEFAULT; /* default */ 1873db966c6cSHong Zhang PetscFunctionReturn(0); 1874db966c6cSHong Zhang } 18759566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("parasails",jac->hypre_type,&flag)); 187616d9e3a6SLisandro Dalcin if (flag) { 18779566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre)); 1878792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsCreate,jac->comm_hypre,&jac->hsolver); 187916d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 188016d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 188116d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 188216d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 188316d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 188416d9e3a6SLisandro Dalcin /* initialize */ 188516d9e3a6SLisandro Dalcin jac->nlevels = 1; 18868966356dSPierre Jolivet jac->threshold = .1; 188716d9e3a6SLisandro Dalcin jac->filter = .1; 188816d9e3a6SLisandro Dalcin jac->loadbal = 0; 18892fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE; 18902fa5cd67SKarl Rupp else jac->logging = (int) PETSC_FALSE; 18912fa5cd67SKarl Rupp 189216d9e3a6SLisandro Dalcin jac->ruse = (int) PETSC_FALSE; 189316d9e3a6SLisandro Dalcin jac->symt = 0; 1894792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels); 1895792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter); 1896792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal); 1897792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging); 1898792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse); 1899792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt); 190016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 190116d9e3a6SLisandro Dalcin } 19029566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("boomeramg",jac->hypre_type,&flag)); 190316d9e3a6SLisandro Dalcin if (flag) { 1904792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGCreate,&jac->hsolver); 190516d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 190616d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 190716d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 190816d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 19099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG)); 19109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG)); 191116d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 191216d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 191316d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 191416d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 191516d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 191616d9e3a6SLisandro Dalcin jac->cycletype = 1; 191716d9e3a6SLisandro Dalcin jac->maxlevels = 25; 191816d9e3a6SLisandro Dalcin jac->maxiter = 1; 19198f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 192016d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 192116d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 192216d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 192316d9e3a6SLisandro Dalcin jac->coarsentype = 6; 192416d9e3a6SLisandro Dalcin jac->measuretype = 0; 19250f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 19266a251517SEike Mueller jac->smoothtype = -1; /* Not set by default */ 1927b9eb5777SEike Mueller jac->smoothnumlevels = 25; 19281810e44eSEike Mueller jac->eu_level = 0; 19291810e44eSEike Mueller jac->eu_droptolerance = 0; 19301810e44eSEike Mueller jac->eu_bj = 0; 1931589dcaf0SStefano Zampini jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */ 19320f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 193316d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 193416d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 193516d9e3a6SLisandro Dalcin jac->relaxorder = 1; 19360f1074feSSatish Balay jac->interptype = 0; 1937589dcaf0SStefano Zampini jac->Rtype = 0; 1938589dcaf0SStefano Zampini jac->Rstrongthreshold = 0.25; 1939589dcaf0SStefano Zampini jac->Rfilterthreshold = 0.0; 1940589dcaf0SStefano Zampini jac->Adroptype = -1; 1941589dcaf0SStefano Zampini jac->Adroptol = 0.0; 19420f1074feSSatish Balay jac->agg_nl = 0; 19436ea7df73SStefano Zampini jac->agg_interptype = 4; 19440f1074feSSatish Balay jac->pmax = 0; 19450f1074feSSatish Balay jac->truncfactor = 0.0; 19460f1074feSSatish Balay jac->agg_num_paths = 1; 1947589dcaf0SStefano Zampini jac->maxc = 9; 1948589dcaf0SStefano Zampini jac->minc = 1; 194922e51d31SStefano Zampini jac->nodal_coarsening = 0; 195022e51d31SStefano Zampini jac->nodal_coarsening_diag = 0; 195122e51d31SStefano Zampini jac->vec_interp_variant = 0; 195222e51d31SStefano Zampini jac->vec_interp_qmax = 0; 195322e51d31SStefano Zampini jac->vec_interp_smooth = PETSC_FALSE; 195422e51d31SStefano Zampini jac->interp_refine = 0; 19558f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 19568f87f92bSBarry Smith jac->nodal_relax_levels = 1; 19576ea7df73SStefano Zampini jac->rap2 = 0; 19586ea7df73SStefano Zampini 19596ea7df73SStefano Zampini /* GPU defaults 19606ea7df73SStefano Zampini from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options 19616ea7df73SStefano Zampini and /src/parcsr_ls/par_amg.c */ 19626ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 19636ea7df73SStefano Zampini jac->keeptranspose = PETSC_TRUE; 19646ea7df73SStefano Zampini jac->mod_rap2 = 1; 19656ea7df73SStefano Zampini jac->coarsentype = 8; 19666ea7df73SStefano Zampini jac->relaxorder = 0; 19676ea7df73SStefano Zampini jac->interptype = 6; 19686ea7df73SStefano Zampini jac->relaxtype[0] = 18; 19696ea7df73SStefano Zampini jac->relaxtype[1] = 18; 19706ea7df73SStefano Zampini jac->agg_interptype = 7; 19716ea7df73SStefano Zampini #else 19726ea7df73SStefano Zampini jac->keeptranspose = PETSC_FALSE; 19736ea7df73SStefano Zampini jac->mod_rap2 = 0; 19746ea7df73SStefano Zampini #endif 1975792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype); 1976792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels); 1977792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter); 1978792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol); 1979792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor); 1980792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold); 1981792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum); 1982792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype); 1983792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype); 1984792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder); 1985792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype); 1986792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl); 1987792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggInterpType,jac->hsolver,jac->agg_interptype); 1988792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax); 1989792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths); 1990792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, jac->relaxtype[0]); /* defaults coarse to 9 */ 1991792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */ 1992792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc); 1993792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc); 19946ea7df73SStefano Zampini /* GPU */ 19956ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0) 1996792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0); 1997792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRAP2,jac->hsolver, jac->rap2); 1998792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetModuleRAP2,jac->hsolver, jac->mod_rap2); 19996ea7df73SStefano Zampini #endif 20006ea7df73SStefano Zampini 2001589dcaf0SStefano Zampini /* AIR */ 20026ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0) 2003792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype); 2004792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold); 2005792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold); 2006792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol); 2007792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype); 20086ea7df73SStefano Zampini #endif 200916d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 201016d9e3a6SLisandro Dalcin } 20119566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ams",jac->hypre_type,&flag)); 20124cb006feSStefano Zampini if (flag) { 20139566063dSJacob Faibussowitsch PetscCall(HYPRE_AMSCreate(&jac->hsolver)); 20144cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 20154cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 20164cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 20174cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 20184cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 20194cb006feSStefano Zampini jac->coords[0] = NULL; 20204cb006feSStefano Zampini jac->coords[1] = NULL; 20214cb006feSStefano Zampini jac->coords[2] = NULL; 2022be14dc20SKerry Key jac->interior = NULL; 20234cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 2024863406b8SStefano Zampini jac->as_print = 0; 2025863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2026863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 20274cb006feSStefano Zampini jac->ams_cycle_type = 13; 20284cb006feSStefano Zampini /* Smoothing options */ 2029863406b8SStefano Zampini jac->as_relax_type = 2; 2030863406b8SStefano Zampini jac->as_relax_times = 1; 2031863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2032863406b8SStefano Zampini jac->as_omega = 1.0; 20334cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2034863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2035863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 20360bdd8552SBarry Smith jac->as_amg_alpha_opts[2] = 6; 2037863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2038863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2039863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 20404cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2041863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2042863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 20430bdd8552SBarry Smith jac->as_amg_beta_opts[2] = 6; 2044863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2045863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2046863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2047792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print); 2048792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter); 2049792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type); 2050792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol); 2051792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type, 2052863406b8SStefano Zampini jac->as_relax_times, 2053863406b8SStefano Zampini jac->as_relax_weight, 2054a74df02fSJacob Faibussowitsch jac->as_omega); 2055792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2056863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2057863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 2058863406b8SStefano Zampini jac->as_amg_alpha_theta, 2059863406b8SStefano Zampini jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2060a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2061792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2062863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2063863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 2064863406b8SStefano Zampini jac->as_amg_beta_theta, 2065863406b8SStefano Zampini jac->as_amg_beta_opts[3], /* AMG interp_type */ 2066a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 206723df4f25SStefano Zampini /* Zero conductivity */ 206823df4f25SStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 206923df4f25SStefano Zampini jac->ams_beta_is_zero_part = PETSC_FALSE; 20704cb006feSStefano Zampini PetscFunctionReturn(0); 20714cb006feSStefano Zampini } 20729566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ads",jac->hypre_type,&flag)); 2073863406b8SStefano Zampini if (flag) { 20749566063dSJacob Faibussowitsch PetscCall(HYPRE_ADSCreate(&jac->hsolver)); 2075863406b8SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ADS; 2076863406b8SStefano Zampini pc->ops->view = PCView_HYPRE_ADS; 2077863406b8SStefano Zampini jac->destroy = HYPRE_ADSDestroy; 2078863406b8SStefano Zampini jac->setup = HYPRE_ADSSetup; 2079863406b8SStefano Zampini jac->solve = HYPRE_ADSSolve; 2080863406b8SStefano Zampini jac->coords[0] = NULL; 2081863406b8SStefano Zampini jac->coords[1] = NULL; 2082863406b8SStefano Zampini jac->coords[2] = NULL; 2083863406b8SStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */ 2084863406b8SStefano Zampini jac->as_print = 0; 2085863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2086863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 2087863406b8SStefano Zampini jac->ads_cycle_type = 13; 2088863406b8SStefano Zampini /* Smoothing options */ 2089863406b8SStefano Zampini jac->as_relax_type = 2; 2090863406b8SStefano Zampini jac->as_relax_times = 1; 2091863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2092863406b8SStefano Zampini jac->as_omega = 1.0; 2093863406b8SStefano Zampini /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2094863406b8SStefano Zampini jac->ams_cycle_type = 14; 2095863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2096863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 2097863406b8SStefano Zampini jac->as_amg_alpha_opts[2] = 6; 2098863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2099863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2100863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 2101863406b8SStefano Zampini /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2102863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2103863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 2104863406b8SStefano Zampini jac->as_amg_beta_opts[2] = 6; 2105863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2106863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2107863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2108792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print); 2109792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter); 2110792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCycleType,jac->hsolver,jac->ams_cycle_type); 2111792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol); 2112792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type, 2113863406b8SStefano Zampini jac->as_relax_times, 2114863406b8SStefano Zampini jac->as_relax_weight, 2115a74df02fSJacob Faibussowitsch jac->as_omega); 2116792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type, /* AMG coarsen type */ 2117863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2118863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2119863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 2120863406b8SStefano Zampini jac->as_amg_alpha_theta, 2121863406b8SStefano Zampini jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2122a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2123792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2124863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2125863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 2126863406b8SStefano Zampini jac->as_amg_beta_theta, 2127863406b8SStefano Zampini jac->as_amg_beta_opts[3], /* AMG interp_type */ 2128a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 2129863406b8SStefano Zampini PetscFunctionReturn(0); 2130863406b8SStefano Zampini } 21319566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 21322fa5cd67SKarl Rupp 21330298fd71SBarry Smith jac->hypre_type = NULL; 213498921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name); 213516d9e3a6SLisandro Dalcin } 213616d9e3a6SLisandro Dalcin 213716d9e3a6SLisandro Dalcin /* 213816d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 213916d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 214016d9e3a6SLisandro Dalcin */ 2141360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc) 214216d9e3a6SLisandro Dalcin { 21434ddd07fcSJed Brown PetscInt indx; 2144db966c6cSHong Zhang const char *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"}; 2145ace3abfcSBarry Smith PetscBool flg; 214616d9e3a6SLisandro Dalcin 214716d9e3a6SLisandro Dalcin PetscFunctionBegin; 2148d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE preconditioner options"); 2149dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,PETSC_STATIC_ARRAY_LENGTH(type),"boomeramg",&indx,&flg)); 215016d9e3a6SLisandro Dalcin if (flg) { 21519566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc,type[indx])); 215202a17cd4SBarry Smith } else { 21539566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc,"boomeramg")); 215416d9e3a6SLisandro Dalcin } 21551baa6e33SBarry Smith if (pc->ops->setfromoptions) PetscCall(pc->ops->setfromoptions(PetscOptionsObject,pc)); 2156d0609cedSBarry Smith PetscOptionsHeadEnd(); 215716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 215816d9e3a6SLisandro Dalcin } 215916d9e3a6SLisandro Dalcin 216016d9e3a6SLisandro Dalcin /*@C 216116d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 216216d9e3a6SLisandro Dalcin 216316d9e3a6SLisandro Dalcin Input Parameters: 216416d9e3a6SLisandro Dalcin + pc - the preconditioner context 2165db966c6cSHong Zhang - name - either euclid, pilut, parasails, boomeramg, ams, ads 216616d9e3a6SLisandro Dalcin 216716d9e3a6SLisandro Dalcin Options Database Keys: 2168db966c6cSHong Zhang -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 216916d9e3a6SLisandro Dalcin 217016d9e3a6SLisandro Dalcin Level: intermediate 217116d9e3a6SLisandro Dalcin 2172db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, 2173db781477SPatrick Sanan `PCHYPRE` 217416d9e3a6SLisandro Dalcin 217516d9e3a6SLisandro Dalcin @*/ 21767087cfbeSBarry Smith PetscErrorCode PCHYPRESetType(PC pc,const char name[]) 217716d9e3a6SLisandro Dalcin { 217816d9e3a6SLisandro Dalcin PetscFunctionBegin; 21790700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 218016d9e3a6SLisandro Dalcin PetscValidCharPointer(name,2); 2181cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name)); 218216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 218316d9e3a6SLisandro Dalcin } 218416d9e3a6SLisandro Dalcin 218516d9e3a6SLisandro Dalcin /*@C 218616d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 218716d9e3a6SLisandro Dalcin 218816d9e3a6SLisandro Dalcin Input Parameter: 218916d9e3a6SLisandro Dalcin . pc - the preconditioner context 219016d9e3a6SLisandro Dalcin 219116d9e3a6SLisandro Dalcin Output Parameter: 2192db966c6cSHong Zhang . name - either euclid, pilut, parasails, boomeramg, ams, ads 219316d9e3a6SLisandro Dalcin 219416d9e3a6SLisandro Dalcin Level: intermediate 219516d9e3a6SLisandro Dalcin 2196db781477SPatrick Sanan .seealso: `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`, 2197db781477SPatrick Sanan `PCHYPRE` 219816d9e3a6SLisandro Dalcin 219916d9e3a6SLisandro Dalcin @*/ 22007087cfbeSBarry Smith PetscErrorCode PCHYPREGetType(PC pc,const char *name[]) 220116d9e3a6SLisandro Dalcin { 220216d9e3a6SLisandro Dalcin PetscFunctionBegin; 22030700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 220416d9e3a6SLisandro Dalcin PetscValidPointer(name,2); 2205cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name)); 220616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 220716d9e3a6SLisandro Dalcin } 220816d9e3a6SLisandro Dalcin 2209db6f9c32SMark Adams /*@C 2210db6f9c32SMark Adams PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use 2211db6f9c32SMark Adams 2212db6f9c32SMark Adams Logically Collective on PC 2213db6f9c32SMark Adams 2214db6f9c32SMark Adams Input Parameters: 2215db6f9c32SMark Adams + pc - the hypre context 2216db6f9c32SMark Adams - type - one of 'cusparse', 'hypre' 2217db6f9c32SMark Adams 2218db6f9c32SMark Adams Options Database Key: 221967b8a455SSatish Balay . -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre 2220db6f9c32SMark Adams 2221db6f9c32SMark Adams Level: intermediate 2222db6f9c32SMark Adams 2223db781477SPatrick Sanan .seealso: `PCMGGalerkinGetMatProductAlgorithm()` 2224db6f9c32SMark Adams 2225db6f9c32SMark Adams @*/ 2226db6f9c32SMark Adams PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc,const char name[]) 2227db6f9c32SMark Adams { 2228db6f9c32SMark Adams PetscFunctionBegin; 2229db6f9c32SMark Adams PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2230cac4c232SBarry Smith PetscTryMethod(pc,"PCMGGalerkinSetMatProductAlgorithm_C",(PC,const char[]),(pc,name)); 2231db6f9c32SMark Adams PetscFunctionReturn(0); 2232db6f9c32SMark Adams } 2233db6f9c32SMark Adams 2234db6f9c32SMark Adams /*@C 2235db6f9c32SMark Adams PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre 2236db6f9c32SMark Adams 2237db6f9c32SMark Adams Not Collective 2238db6f9c32SMark Adams 2239db6f9c32SMark Adams Input Parameter: 2240db6f9c32SMark Adams . pc - the multigrid context 2241db6f9c32SMark Adams 2242db6f9c32SMark Adams Output Parameter: 2243db6f9c32SMark Adams . name - one of 'cusparse', 'hypre' 2244db6f9c32SMark Adams 2245db6f9c32SMark Adams Level: intermediate 2246db6f9c32SMark Adams 2247db781477SPatrick Sanan .seealso: `PCMGGalerkinSetMatProductAlgorithm()` 2248db6f9c32SMark Adams 2249db6f9c32SMark Adams @*/ 2250db6f9c32SMark Adams PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc,const char *name[]) 2251db6f9c32SMark Adams { 2252db6f9c32SMark Adams PetscFunctionBegin; 2253db6f9c32SMark Adams PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2254cac4c232SBarry Smith PetscTryMethod(pc,"PCMGGalerkinGetMatProductAlgorithm_C",(PC,const char*[]),(pc,name)); 2255db6f9c32SMark Adams PetscFunctionReturn(0); 2256db6f9c32SMark Adams } 2257db6f9c32SMark Adams 225816d9e3a6SLisandro Dalcin /*MC 225916d9e3a6SLisandro Dalcin PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre 226016d9e3a6SLisandro Dalcin 226116d9e3a6SLisandro Dalcin Options Database Keys: 2262db966c6cSHong Zhang + -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 2263ead8c081SBarry Smith . -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal()) 2264ead8c081SBarry Smith . -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant()) 2265ead8c081SBarry Smith - Many others, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX preconditioner 226616d9e3a6SLisandro Dalcin 226716d9e3a6SLisandro Dalcin Level: intermediate 226816d9e3a6SLisandro Dalcin 226995452b02SPatrick Sanan Notes: 227095452b02SPatrick Sanan Apart from pc_hypre_type (for which there is PCHYPRESetType()), 227116d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 227216d9e3a6SLisandro Dalcin or with PetscOptionsSetValue(), there are no functions to set them) 227316d9e3a6SLisandro Dalcin 2274c231f9e3SBarryFSmith The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations 22750f1074feSSatish Balay (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if 22760f1074feSSatish Balay -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner 2277c231f9e3SBarryFSmith (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of 22788f87f92bSBarry Smith iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations 22790f1074feSSatish Balay and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10 22800f1074feSSatish Balay then AT MOST twenty V-cycles of boomeramg will be called. 228116d9e3a6SLisandro Dalcin 22820f1074feSSatish Balay Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation 22830f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 22840f1074feSSatish Balay Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi. 228516d9e3a6SLisandro Dalcin If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly 228616d9e3a6SLisandro Dalcin and use -ksp_max_it to control the number of V-cycles. 228716d9e3a6SLisandro Dalcin (see the PETSc FAQ.html at the PETSc website under the Documentation tab). 228816d9e3a6SLisandro Dalcin 228916d9e3a6SLisandro Dalcin 2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option 229016d9e3a6SLisandro Dalcin -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L. 229116d9e3a6SLisandro Dalcin 22925272c319SBarry Smith MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use 2293fdd15c9aSJunchao Zhang the following two options: 22940b1a5bd9SEric Chamberland 22959e5bc791SBarry Smith See PCPFMG for access to the hypre Struct PFMG solver 22969e5bc791SBarry Smith 2297ead8c081SBarry Smith GPU Notes: 2298ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda 2299ead8c081SBarry Smith Then pass VECCUDA vectors and MATAIJCUSPARSE matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2300ead8c081SBarry Smith 2301ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip 2302ead8c081SBarry Smith Then pass VECHIP vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2303ead8c081SBarry Smith 2304db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, 2305db781477SPatrick Sanan `PCHYPRESetType()`, `PCPFMG` 230616d9e3a6SLisandro Dalcin 230716d9e3a6SLisandro Dalcin M*/ 230816d9e3a6SLisandro Dalcin 23098cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 231016d9e3a6SLisandro Dalcin { 231116d9e3a6SLisandro Dalcin PC_HYPRE *jac; 231216d9e3a6SLisandro Dalcin 231316d9e3a6SLisandro Dalcin PetscFunctionBegin; 23149566063dSJacob Faibussowitsch PetscCall(PetscNewLog(pc,&jac)); 23152fa5cd67SKarl Rupp 231616d9e3a6SLisandro Dalcin pc->data = jac; 23178695de01SBarry Smith pc->ops->reset = PCReset_HYPRE; 231816d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 231916d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 232016d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 232116d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 232216d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 23239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE)); 23249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE)); 23259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE)); 23269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE)); 23279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE)); 23289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE)); 23299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE)); 2330be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREAMSSetInteriorNodes_C",PCHYPREAMSSetInteriorNodes_HYPRE)); 23319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE)); 23329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG)); 23339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG)); 23346ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 23356ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 23369566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 23376ea7df73SStefano Zampini #endif 23386ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 23399566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 23406ea7df73SStefano Zampini #endif 23416ea7df73SStefano Zampini #endif 234216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 234316d9e3a6SLisandro Dalcin } 2344ebc551c0SBarry Smith 2345f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/ 2346f91d8e95SBarry Smith 2347ebc551c0SBarry Smith typedef struct { 234868326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 2349f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 23509e5bc791SBarry Smith 23519e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 23524ddd07fcSJed Brown PetscInt its; 23539e5bc791SBarry Smith double tol; 23544ddd07fcSJed Brown PetscInt relax_type; 23554ddd07fcSJed Brown PetscInt rap_type; 23564ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 23574ddd07fcSJed Brown PetscInt max_levels; 23580be8cd64Sftrigaux PetscInt skip_relax; 23590be8cd64Sftrigaux PetscBool print_statistics; 2360ebc551c0SBarry Smith } PC_PFMG; 2361ebc551c0SBarry Smith 2362ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc) 2363ebc551c0SBarry Smith { 2364f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 2365ebc551c0SBarry Smith 2366ebc551c0SBarry Smith PetscFunctionBegin; 2367792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy,ex->hsolver); 23689566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 23699566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 2370ebc551c0SBarry Smith PetscFunctionReturn(0); 2371ebc551c0SBarry Smith } 2372ebc551c0SBarry Smith 23739e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"}; 23749e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"}; 23759e5bc791SBarry Smith 2376ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer) 2377ebc551c0SBarry Smith { 2378ace3abfcSBarry Smith PetscBool iascii; 2379f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 2380ebc551c0SBarry Smith 2381ebc551c0SBarry Smith PetscFunctionBegin; 23829566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 23839e5bc791SBarry Smith if (iascii) { 23849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE PFMG preconditioning\n")); 238563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max iterations %" PetscInt_FMT "\n",ex->its)); 23869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," tolerance %g\n",ex->tol)); 23879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," relax type %s\n",PFMGRelaxType[ex->relax_type])); 23889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," RAP type %s\n",PFMGRAPType[ex->rap_type])); 238963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n",ex->num_pre_relax,ex->num_post_relax)); 239063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max levels %" PetscInt_FMT "\n",ex->max_levels)); 23910be8cd64Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer," skip relax %" PetscInt_FMT "\n",ex->skip_relax)); 23929e5bc791SBarry Smith } 2393ebc551c0SBarry Smith PetscFunctionReturn(0); 2394ebc551c0SBarry Smith } 2395ebc551c0SBarry Smith 23964416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc) 2397ebc551c0SBarry Smith { 2398f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 2399ebc551c0SBarry Smith 2400ebc551c0SBarry Smith PetscFunctionBegin; 2401d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"PFMG options"); 24020be8cd64Sftrigaux PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",ex->print_statistics,&ex->print_statistics,NULL)); 24039566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL)); 2404792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter,ex->hsolver,ex->its); 24059566063dSJacob 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)); 2406792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax,ex->hsolver,ex->num_pre_relax); 24079566063dSJacob 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)); 2408792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax,ex->hsolver,ex->num_post_relax); 24099e5bc791SBarry Smith 24109566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL)); 2411792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxLevels,ex->hsolver,ex->max_levels); 24123b46a515SGlenn Hammond 24139566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL)); 2414792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol,ex->hsolver,ex->tol); 2415dd39110bSPierre 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)); 2416792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRelaxType,ex->hsolver, ex->relax_type); 2417dd39110bSPierre 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)); 2418792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRAPType,ex->hsolver, ex->rap_type); 24190be8cd64Sftrigaux 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)); 24200be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetSkipRelax,ex->hsolver, ex->skip_relax); 2421d0609cedSBarry Smith PetscOptionsHeadEnd(); 2422ebc551c0SBarry Smith PetscFunctionReturn(0); 2423ebc551c0SBarry Smith } 2424ebc551c0SBarry Smith 2425f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y) 2426f91d8e95SBarry Smith { 2427f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 2428d9ca1df4SBarry Smith PetscScalar *yy; 2429d9ca1df4SBarry Smith const PetscScalar *xx; 24304ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 24312cf14000SStefano Zampini HYPRE_Int hlower[3],hupper[3]; 243268326731SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 2433f91d8e95SBarry Smith 2434f91d8e95SBarry Smith PetscFunctionBegin; 24359566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 24369566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2])); 24372cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2438f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 2439f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 2440f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 24412cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 24422cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 24432cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 24442cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 24452cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 24462cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2447f91d8e95SBarry Smith 2448f91d8e95SBarry Smith /* copy x values over to hypre */ 2449792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetConstantValues,mx->hb,0.0); 24509566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xx)); 2451792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetBoxValues,mx->hb,hlower,hupper,(HYPRE_Complex*)xx); 24529566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xx)); 2453792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorAssemble,mx->hb); 2454792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSolve,ex->hsolver,mx->hmat,mx->hb,mx->hx); 2455f91d8e95SBarry Smith 2456f91d8e95SBarry Smith /* copy solution values back to PETSc */ 24579566063dSJacob Faibussowitsch PetscCall(VecGetArray(y,&yy)); 2458792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorGetBoxValues,mx->hx,hlower,hupper,(HYPRE_Complex*)yy); 24599566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y,&yy)); 2460f91d8e95SBarry Smith PetscFunctionReturn(0); 2461f91d8e95SBarry Smith } 2462f91d8e95SBarry Smith 2463ace3abfcSBarry Smith 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) 24649e5bc791SBarry Smith { 24659e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG*)pc->data; 24662cf14000SStefano Zampini HYPRE_Int oits; 24679e5bc791SBarry Smith 24689e5bc791SBarry Smith PetscFunctionBegin; 24699566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 2470792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter,jac->hsolver,its*jac->its); 2471792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol,jac->hsolver,rtol); 24729e5bc791SBarry Smith 24739566063dSJacob Faibussowitsch PetscCall(PCApply_PFMG(pc,b,y)); 2474792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGGetNumIterations,jac->hsolver,&oits); 24759e5bc791SBarry Smith *outits = oits; 24769e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 24779e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 2478792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol,jac->hsolver,jac->tol); 2479792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter,jac->hsolver,jac->its); 24809e5bc791SBarry Smith PetscFunctionReturn(0); 24819e5bc791SBarry Smith } 24829e5bc791SBarry Smith 24833a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc) 24843a32d3dbSGlenn Hammond { 24853a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG*) pc->data; 24863a32d3dbSGlenn Hammond Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 2487ace3abfcSBarry Smith PetscBool flg; 24883a32d3dbSGlenn Hammond 24893a32d3dbSGlenn Hammond PetscFunctionBegin; 24909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg)); 249128b400f6SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner"); 24923a32d3dbSGlenn Hammond 24933a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 2494792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy,ex->hsolver); 2495792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver); 24960be8cd64Sftrigaux 24970be8cd64Sftrigaux // Print Hypre statistics about the solve process 24980be8cd64Sftrigaux if (ex->print_statistics) PetscCallExternal(HYPRE_StructPFMGSetPrintLevel,ex->hsolver,3); 24990be8cd64Sftrigaux 25000be8cd64Sftrigaux // The hypre options must be repeated here because the StructPFMG was destroyed and recreated 25010be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxIter ,ex->hsolver, ex->its); 25020be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax ,ex->hsolver, ex->num_pre_relax); 25030be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax,ex->hsolver, ex->num_post_relax); 25040be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxLevels ,ex->hsolver, ex->max_levels); 25050be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetTol ,ex->hsolver, ex->tol); 25060be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRelaxType ,ex->hsolver, ex->relax_type); 25070be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRAPType ,ex->hsolver, ex->rap_type); 25080be8cd64Sftrigaux 2509792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetup,ex->hsolver,mx->hmat,mx->hb,mx->hx); 2510792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetZeroGuess,ex->hsolver); 25113a32d3dbSGlenn Hammond PetscFunctionReturn(0); 25123a32d3dbSGlenn Hammond } 25133a32d3dbSGlenn Hammond 2514ebc551c0SBarry Smith /*MC 2515ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 2516ebc551c0SBarry Smith 2517ebc551c0SBarry Smith Level: advanced 2518ebc551c0SBarry Smith 25199e5bc791SBarry Smith Options Database: 252067b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner 252167b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve 252267b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve 252367b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG 25249e5bc791SBarry 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 25250be8cd64Sftrigaux . -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 25260be8cd64Sftrigaux - -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, one of 0,1 2527f91d8e95SBarry Smith 252895452b02SPatrick Sanan Notes: 252995452b02SPatrick Sanan This is for CELL-centered descretizations 25309e5bc791SBarry Smith 25318e395302SJed Brown This must be used with the MATHYPRESTRUCT matrix type. 2532aa219208SBarry Smith This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA. 25339e5bc791SBarry Smith 2534db781477SPatrick Sanan .seealso: `PCMG`, `MATHYPRESTRUCT` 2535ebc551c0SBarry Smith M*/ 2536ebc551c0SBarry Smith 25378cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 2538ebc551c0SBarry Smith { 2539ebc551c0SBarry Smith PC_PFMG *ex; 2540ebc551c0SBarry Smith 2541ebc551c0SBarry Smith PetscFunctionBegin; 25429566063dSJacob Faibussowitsch PetscCall(PetscNew(&ex)); \ 254368326731SBarry Smith pc->data = ex; 2544ebc551c0SBarry Smith 25459e5bc791SBarry Smith ex->its = 1; 25469e5bc791SBarry Smith ex->tol = 1.e-8; 25479e5bc791SBarry Smith ex->relax_type = 1; 25489e5bc791SBarry Smith ex->rap_type = 0; 25499e5bc791SBarry Smith ex->num_pre_relax = 1; 25509e5bc791SBarry Smith ex->num_post_relax = 1; 25513b46a515SGlenn Hammond ex->max_levels = 0; 25520be8cd64Sftrigaux ex->skip_relax = 0; 25530be8cd64Sftrigaux ex->print_statistics = PETSC_FALSE; 25549e5bc791SBarry Smith 2555ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 2556ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 2557ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 2558f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 25599e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 256068326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 25612fa5cd67SKarl Rupp 25629566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 2563792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver); 2564ebc551c0SBarry Smith PetscFunctionReturn(0); 2565ebc551c0SBarry Smith } 2566d851a50bSGlenn Hammond 2567325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/ 2568325fc9f4SBarry Smith 2569d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 2570d851a50bSGlenn Hammond typedef struct { 2571d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 2572d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 2573d851a50bSGlenn Hammond 2574d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 25754ddd07fcSJed Brown PetscInt its; 2576d851a50bSGlenn Hammond double tol; 25774ddd07fcSJed Brown PetscInt relax_type; 25784ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 2579d851a50bSGlenn Hammond } PC_SysPFMG; 2580d851a50bSGlenn Hammond 2581d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc) 2582d851a50bSGlenn Hammond { 2583d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2584d851a50bSGlenn Hammond 2585d851a50bSGlenn Hammond PetscFunctionBegin; 2586792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy,ex->ss_solver); 25879566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 25889566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 2589d851a50bSGlenn Hammond PetscFunctionReturn(0); 2590d851a50bSGlenn Hammond } 2591d851a50bSGlenn Hammond 2592d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"}; 2593d851a50bSGlenn Hammond 2594d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer) 2595d851a50bSGlenn Hammond { 2596ace3abfcSBarry Smith PetscBool iascii; 2597d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2598d851a50bSGlenn Hammond 2599d851a50bSGlenn Hammond PetscFunctionBegin; 26009566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 2601d851a50bSGlenn Hammond if (iascii) { 26029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG preconditioning\n")); 260363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max iterations %" PetscInt_FMT "\n",ex->its)); 26049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," tolerance %g\n",ex->tol)); 26059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," relax type %s\n",PFMGRelaxType[ex->relax_type])); 260663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n",ex->num_pre_relax,ex->num_post_relax)); 2607d851a50bSGlenn Hammond } 2608d851a50bSGlenn Hammond PetscFunctionReturn(0); 2609d851a50bSGlenn Hammond } 2610d851a50bSGlenn Hammond 26114416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc) 2612d851a50bSGlenn Hammond { 2613d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2614ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2615d851a50bSGlenn Hammond 2616d851a50bSGlenn Hammond PetscFunctionBegin; 2617d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"SysPFMG options"); 26189566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL)); 2619d851a50bSGlenn Hammond if (flg) { 2620792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetPrintLevel,ex->ss_solver,3); 2621d851a50bSGlenn Hammond } 26229566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL)); 2623792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,ex->ss_solver,ex->its); 26249566063dSJacob 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)); 2625792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPreRelax,ex->ss_solver,ex->num_pre_relax); 26269566063dSJacob 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)); 2627792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPostRelax,ex->ss_solver,ex->num_post_relax); 2628d851a50bSGlenn Hammond 26299566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL)); 2630792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol,ex->ss_solver,ex->tol); 2631dd39110bSPierre 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)); 2632792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetRelaxType,ex->ss_solver, ex->relax_type); 2633d0609cedSBarry Smith PetscOptionsHeadEnd(); 2634d851a50bSGlenn Hammond PetscFunctionReturn(0); 2635d851a50bSGlenn Hammond } 2636d851a50bSGlenn Hammond 2637d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y) 2638d851a50bSGlenn Hammond { 2639d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2640d9ca1df4SBarry Smith PetscScalar *yy; 2641d9ca1df4SBarry Smith const PetscScalar *xx; 26424ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 26432cf14000SStefano Zampini HYPRE_Int hlower[3],hupper[3]; 2644d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 26454ddd07fcSJed Brown PetscInt ordering= mx->dofs_order; 26464ddd07fcSJed Brown PetscInt nvars = mx->nvars; 26474ddd07fcSJed Brown PetscInt part = 0; 26484ddd07fcSJed Brown PetscInt size; 26494ddd07fcSJed Brown PetscInt i; 2650d851a50bSGlenn Hammond 2651d851a50bSGlenn Hammond PetscFunctionBegin; 26529566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 26539566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2])); 26542cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2655d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 2656d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 2657d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 26582cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 26592cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 26602cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 26612cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 26622cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 26632cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2664d851a50bSGlenn Hammond 2665d851a50bSGlenn Hammond size = 1; 26662fa5cd67SKarl Rupp for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1); 26672fa5cd67SKarl Rupp 2668d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 2669d851a50bSGlenn Hammond if (ordering) { 2670792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0); 26719566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xx)); 2672792fecdfSBarry Smith for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))); 26739566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xx)); 2674792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble,mx->ss_b); 2675792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructMatrixMatvec,1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x); 2676792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x); 2677d851a50bSGlenn Hammond 2678d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 26799566063dSJacob Faibussowitsch PetscCall(VecGetArray(y,&yy)); 2680792fecdfSBarry Smith for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))); 26819566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y,&yy)); 2682a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 2683d851a50bSGlenn Hammond PetscScalar *z; 26844ddd07fcSJed Brown PetscInt j, k; 2685d851a50bSGlenn Hammond 26869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvars*size,&z)); 2687792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0); 26889566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xx)); 2689d851a50bSGlenn Hammond 2690d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 2691d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 2692d851a50bSGlenn Hammond k= i*nvars; 26932fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j]; 2694d851a50bSGlenn Hammond } 2695792fecdfSBarry Smith for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))); 26969566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xx)); 2697792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble,mx->ss_b); 2698792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x); 2699d851a50bSGlenn Hammond 2700d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 27019566063dSJacob Faibussowitsch PetscCall(VecGetArray(y,&yy)); 2702792fecdfSBarry Smith for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))); 2703d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 2704d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 2705d851a50bSGlenn Hammond k= i*nvars; 27062fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i]; 2707d851a50bSGlenn Hammond } 27089566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y,&yy)); 27099566063dSJacob Faibussowitsch PetscCall(PetscFree(z)); 2710d851a50bSGlenn Hammond } 2711d851a50bSGlenn Hammond PetscFunctionReturn(0); 2712d851a50bSGlenn Hammond } 2713d851a50bSGlenn Hammond 2714ace3abfcSBarry Smith 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) 2715d851a50bSGlenn Hammond { 2716d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG*)pc->data; 27172cf14000SStefano Zampini HYPRE_Int oits; 2718d851a50bSGlenn Hammond 2719d851a50bSGlenn Hammond PetscFunctionBegin; 27209566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 2721792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,its*jac->its); 2722792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,rtol); 27239566063dSJacob Faibussowitsch PetscCall(PCApply_SysPFMG(pc,b,y)); 2724792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGGetNumIterations,jac->ss_solver,&oits); 2725d851a50bSGlenn Hammond *outits = oits; 2726d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 2727d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 2728792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,jac->tol); 2729792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,jac->its); 2730d851a50bSGlenn Hammond PetscFunctionReturn(0); 2731d851a50bSGlenn Hammond } 2732d851a50bSGlenn Hammond 2733d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc) 2734d851a50bSGlenn Hammond { 2735d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2736d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 2737ace3abfcSBarry Smith PetscBool flg; 2738d851a50bSGlenn Hammond 2739d851a50bSGlenn Hammond PetscFunctionBegin; 27409566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg)); 274128b400f6SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner"); 2742d851a50bSGlenn Hammond 2743d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 2744792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy,ex->ss_solver); 2745792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver); 2746792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetZeroGuess,ex->ss_solver); 2747792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetup,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x); 2748d851a50bSGlenn Hammond PetscFunctionReturn(0); 2749d851a50bSGlenn Hammond } 2750d851a50bSGlenn Hammond 2751d851a50bSGlenn Hammond /*MC 2752d851a50bSGlenn Hammond PCSysPFMG - the hypre SysPFMG multigrid solver 2753d851a50bSGlenn Hammond 2754d851a50bSGlenn Hammond Level: advanced 2755d851a50bSGlenn Hammond 2756d851a50bSGlenn Hammond Options Database: 275767b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner 275867b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid 275967b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid 276067b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG 276167b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles 2762d851a50bSGlenn Hammond 276395452b02SPatrick Sanan Notes: 276495452b02SPatrick Sanan This is for CELL-centered descretizations 2765d851a50bSGlenn Hammond 2766f6680f47SSatish Balay This must be used with the MATHYPRESSTRUCT matrix type. 2767aa219208SBarry Smith This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA. 2768d851a50bSGlenn Hammond Also, only cell-centered variables. 2769d851a50bSGlenn Hammond 2770db781477SPatrick Sanan .seealso: `PCMG`, `MATHYPRESSTRUCT` 2771d851a50bSGlenn Hammond M*/ 2772d851a50bSGlenn Hammond 27738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 2774d851a50bSGlenn Hammond { 2775d851a50bSGlenn Hammond PC_SysPFMG *ex; 2776d851a50bSGlenn Hammond 2777d851a50bSGlenn Hammond PetscFunctionBegin; 27789566063dSJacob Faibussowitsch PetscCall(PetscNew(&ex)); \ 2779d851a50bSGlenn Hammond pc->data = ex; 2780d851a50bSGlenn Hammond 2781d851a50bSGlenn Hammond ex->its = 1; 2782d851a50bSGlenn Hammond ex->tol = 1.e-8; 2783d851a50bSGlenn Hammond ex->relax_type = 1; 2784d851a50bSGlenn Hammond ex->num_pre_relax = 1; 2785d851a50bSGlenn Hammond ex->num_post_relax = 1; 2786d851a50bSGlenn Hammond 2787d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 2788d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 2789d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 2790d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 2791d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 2792d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 27932fa5cd67SKarl Rupp 27949566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 2795792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver); 2796d851a50bSGlenn Hammond PetscFunctionReturn(0); 2797d851a50bSGlenn Hammond } 27981c188c59Sftrigaux 27991c188c59Sftrigaux /* ---------------------------------------------------------------------------------------------------------------------------------*/ 28001c188c59Sftrigaux 28011c188c59Sftrigaux // PC SMG 28021c188c59Sftrigaux typedef struct { 28031c188c59Sftrigaux MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 28041c188c59Sftrigaux HYPRE_StructSolver hsolver; 28051c188c59Sftrigaux PetscInt its; /* keep copy of SMG options used so may view them */ 28061c188c59Sftrigaux double tol; 28071c188c59Sftrigaux PetscBool print_statistics; 28081c188c59Sftrigaux PetscInt num_pre_relax,num_post_relax; 28091c188c59Sftrigaux } PC_SMG; 28101c188c59Sftrigaux 28111c188c59Sftrigaux PetscErrorCode PCDestroy_SMG(PC pc) 28121c188c59Sftrigaux { 28131c188c59Sftrigaux PC_SMG *ex = (PC_SMG*) pc->data; 28141c188c59Sftrigaux 28151c188c59Sftrigaux PetscFunctionBegin; 28161c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy,ex->hsolver); 28171c188c59Sftrigaux PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 28181c188c59Sftrigaux PetscCall(PetscFree(pc->data)); 28191c188c59Sftrigaux PetscFunctionReturn(0); 28201c188c59Sftrigaux } 28211c188c59Sftrigaux 28221c188c59Sftrigaux PetscErrorCode PCView_SMG(PC pc,PetscViewer viewer) 28231c188c59Sftrigaux { 28241c188c59Sftrigaux PetscBool iascii; 28251c188c59Sftrigaux PC_SMG *ex = (PC_SMG*) pc->data; 28261c188c59Sftrigaux 28271c188c59Sftrigaux PetscFunctionBegin; 28281c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 28291c188c59Sftrigaux if (iascii) { 28301c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE SMG preconditioning\n")); 28311c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer," max iterations %" PetscInt_FMT "\n",ex->its)); 28321c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer," tolerance %g\n",ex->tol)); 28331c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer," number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n",ex->num_pre_relax,ex->num_post_relax)); 28341c188c59Sftrigaux } 28351c188c59Sftrigaux PetscFunctionReturn(0); 28361c188c59Sftrigaux } 28371c188c59Sftrigaux 28381c188c59Sftrigaux PetscErrorCode PCSetFromOptions_SMG(PetscOptionItems *PetscOptionsObject,PC pc) 28391c188c59Sftrigaux { 28401c188c59Sftrigaux PC_SMG *ex = (PC_SMG*) pc->data; 28411c188c59Sftrigaux 28421c188c59Sftrigaux PetscFunctionBegin; 28431c188c59Sftrigaux PetscOptionsHeadBegin(PetscOptionsObject,"SMG options"); 28441c188c59Sftrigaux 28451c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_its","Number of iterations of SMG to use as preconditioner","HYPRE_StructSMGSetMaxIter",ex->its,&ex->its,NULL)); 28461c188c59Sftrigaux 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)); 28471c188c59Sftrigaux 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)); 28481c188c59Sftrigaux PetscCall(PetscOptionsReal("-pc_smg_tol","Tolerance of SMG","HYPRE_StructSMGSetTol",ex->tol,&ex->tol,NULL)); 28491c188c59Sftrigaux 28501c188c59Sftrigaux PetscOptionsHeadEnd(); 28511c188c59Sftrigaux PetscFunctionReturn(0); 28521c188c59Sftrigaux } 28531c188c59Sftrigaux 28541c188c59Sftrigaux PetscErrorCode PCApply_SMG(PC pc,Vec x,Vec y) 28551c188c59Sftrigaux { 28561c188c59Sftrigaux PC_SMG *ex = (PC_SMG*) pc->data; 28571c188c59Sftrigaux PetscScalar *yy; 28581c188c59Sftrigaux const PetscScalar *xx; 28591c188c59Sftrigaux PetscInt ilower[3],iupper[3]; 28601c188c59Sftrigaux HYPRE_Int hlower[3],hupper[3]; 28611c188c59Sftrigaux Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 28621c188c59Sftrigaux 28631c188c59Sftrigaux PetscFunctionBegin; 28641c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 28651c188c59Sftrigaux PetscCall(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2])); 28661c188c59Sftrigaux /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 28671c188c59Sftrigaux iupper[0] += ilower[0] - 1; 28681c188c59Sftrigaux iupper[1] += ilower[1] - 1; 28691c188c59Sftrigaux iupper[2] += ilower[2] - 1; 28701c188c59Sftrigaux hlower[0] = (HYPRE_Int)ilower[0]; 28711c188c59Sftrigaux hlower[1] = (HYPRE_Int)ilower[1]; 28721c188c59Sftrigaux hlower[2] = (HYPRE_Int)ilower[2]; 28731c188c59Sftrigaux hupper[0] = (HYPRE_Int)iupper[0]; 28741c188c59Sftrigaux hupper[1] = (HYPRE_Int)iupper[1]; 28751c188c59Sftrigaux hupper[2] = (HYPRE_Int)iupper[2]; 28761c188c59Sftrigaux 28771c188c59Sftrigaux /* copy x values over to hypre */ 28781c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetConstantValues,mx->hb,0.0); 28791c188c59Sftrigaux PetscCall(VecGetArrayRead(x,&xx)); 28801c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetBoxValues,mx->hb,hlower,hupper,(HYPRE_Complex*)xx); 28811c188c59Sftrigaux PetscCall(VecRestoreArrayRead(x,&xx)); 28821c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorAssemble,mx->hb); 28831c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSolve,ex->hsolver,mx->hmat,mx->hb,mx->hx); 28841c188c59Sftrigaux 28851c188c59Sftrigaux /* copy solution values back to PETSc */ 28861c188c59Sftrigaux PetscCall(VecGetArray(y,&yy)); 28871c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorGetBoxValues,mx->hx,hlower,hupper,(HYPRE_Complex*)yy); 28881c188c59Sftrigaux PetscCall(VecRestoreArray(y,&yy)); 28891c188c59Sftrigaux PetscFunctionReturn(0); 28901c188c59Sftrigaux } 28911c188c59Sftrigaux 28921c188c59Sftrigaux 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) 28931c188c59Sftrigaux { 28941c188c59Sftrigaux PC_SMG *jac = (PC_SMG*)pc->data; 28951c188c59Sftrigaux HYPRE_Int oits; 28961c188c59Sftrigaux 28971c188c59Sftrigaux PetscFunctionBegin; 28981c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 28991c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter,jac->hsolver,its*jac->its); 29001c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol,jac->hsolver,rtol); 29011c188c59Sftrigaux 29021c188c59Sftrigaux PetscCall(PCApply_SMG(pc,b,y)); 29031c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGGetNumIterations,jac->hsolver,&oits); 29041c188c59Sftrigaux *outits = oits; 29051c188c59Sftrigaux if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 29061c188c59Sftrigaux else *reason = PCRICHARDSON_CONVERGED_RTOL; 29071c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol,jac->hsolver,jac->tol); 29081c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter,jac->hsolver,jac->its); 29091c188c59Sftrigaux PetscFunctionReturn(0); 29101c188c59Sftrigaux } 29111c188c59Sftrigaux 29121c188c59Sftrigaux PetscErrorCode PCSetUp_SMG(PC pc) 29131c188c59Sftrigaux { 29141c188c59Sftrigaux PetscInt i, dim; 29151c188c59Sftrigaux PC_SMG *ex = (PC_SMG*) pc->data; 29161c188c59Sftrigaux Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 29171c188c59Sftrigaux PetscBool flg; 29181c188c59Sftrigaux DMBoundaryType p[3]; 29191c188c59Sftrigaux PetscInt M[3]; 29201c188c59Sftrigaux 29211c188c59Sftrigaux PetscFunctionBegin; 29221c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg)); 29231c188c59Sftrigaux PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner"); 29241c188c59Sftrigaux 29251c188c59Sftrigaux PetscCall(DMDAGetInfo(mx->da,&dim,&M[0], &M[1], &M[2],0,0,0,0,0,&p[0],&p[1],&p[2],0)); 29261c188c59Sftrigaux // Check if power of 2 in periodic directions 29271c188c59Sftrigaux for (i=0;i<dim;i++){ 29281c188c59Sftrigaux if (((M[i] & (M[i] - 1)) != 0) && (p[i]==DM_BOUNDARY_PERIODIC)) { 29291c188c59Sftrigaux 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]); 29301c188c59Sftrigaux } 29311c188c59Sftrigaux } 29321c188c59Sftrigaux 29331c188c59Sftrigaux /* create the hypre solver object and set its information */ 29341c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy,(ex->hsolver)); 29351c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate,ex->hcomm,&ex->hsolver); 29361c188c59Sftrigaux // The hypre options must be set here and not in SetFromOptions because it is created here! 29371c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter,ex->hsolver,ex->its); 29381c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPreRelax,ex->hsolver,ex->num_pre_relax); 29391c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPostRelax,ex->hsolver,ex->num_post_relax); 29401c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol,ex->hsolver,ex->tol); 29411c188c59Sftrigaux 29421c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetup,ex->hsolver,mx->hmat,mx->hb,mx->hx); 29431c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetZeroGuess,ex->hsolver); 29441c188c59Sftrigaux PetscFunctionReturn(0); 29451c188c59Sftrigaux } 29461c188c59Sftrigaux 29471c188c59Sftrigaux /*MC 2948*5cb80ecdSBarry Smith PCSMG - the hypre (structured grid) SMG multigrid solver 29491c188c59Sftrigaux 29501c188c59Sftrigaux Level: advanced 29511c188c59Sftrigaux 29521c188c59Sftrigaux Options Database: 2953*5cb80ecdSBarry Smith + -pc_smg_its <its> - number of iterations of SMG to use as preconditioner 2954*5cb80ecdSBarry Smith . -pc_smg_num_pre_relax <steps> - number of smoothing steps before coarse grid 2955*5cb80ecdSBarry Smith . -pc_smg_num_post_relax <steps> - number of smoothing steps after coarse grid 2956*5cb80ecdSBarry Smith - -pc_smg_tol <tol> - tolerance of SMG 29571c188c59Sftrigaux 29581c188c59Sftrigaux Notes: 29591c188c59Sftrigaux This is for CELL-centered descretizations 29601c188c59Sftrigaux 2961*5cb80ecdSBarry Smith This must be used with the `MATHYPRESTRUCT` `MatType`. 2962*5cb80ecdSBarry Smith This support is less general than in hypre, it supports only one block per process defined by a PETSc `DMDA`. 29631c188c59Sftrigaux 29641c188c59Sftrigaux .seealso: PCMG, MATHYPRESTRUCT, PCPFMG 29651c188c59Sftrigaux M*/ 29661c188c59Sftrigaux 29671c188c59Sftrigaux PETSC_EXTERN PetscErrorCode PCCreate_SMG(PC pc) 29681c188c59Sftrigaux { 29691c188c59Sftrigaux PC_SMG *ex; 29701c188c59Sftrigaux 29711c188c59Sftrigaux PetscFunctionBegin; 29721c188c59Sftrigaux PetscCall(PetscNew(&ex)); \ 29731c188c59Sftrigaux pc->data = ex; 29741c188c59Sftrigaux 29751c188c59Sftrigaux ex->its = 1; 29761c188c59Sftrigaux ex->tol = 1.e-8; 29771c188c59Sftrigaux ex->num_pre_relax = 1; 29781c188c59Sftrigaux ex->num_post_relax = 1; 29791c188c59Sftrigaux 29801c188c59Sftrigaux pc->ops->setfromoptions = PCSetFromOptions_SMG; 29811c188c59Sftrigaux pc->ops->view = PCView_SMG; 29821c188c59Sftrigaux pc->ops->destroy = PCDestroy_SMG; 29831c188c59Sftrigaux pc->ops->apply = PCApply_SMG; 29841c188c59Sftrigaux pc->ops->applyrichardson = PCApplyRichardson_SMG; 29851c188c59Sftrigaux pc->ops->setup = PCSetUp_SMG; 29861c188c59Sftrigaux 29871c188c59Sftrigaux PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 29881c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate,ex->hcomm,&ex->hsolver); 29891c188c59Sftrigaux PetscFunctionReturn(0); 29901c188c59Sftrigaux } 2991