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]; 1386bf688a0SCe Qin Mat RT_PiFull, RT_Pi[3]; 1396bf688a0SCe Qin Mat ND_PiFull, ND_Pi[3]; 1404cb006feSStefano Zampini PetscBool ams_beta_is_zero; 14123df4f25SStefano Zampini PetscBool ams_beta_is_zero_part; 14223df4f25SStefano Zampini PetscInt ams_proj_freq; 14316d9e3a6SLisandro Dalcin } PC_HYPRE; 14416d9e3a6SLisandro Dalcin 145d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver) 146d2128fa2SBarry Smith { 147d2128fa2SBarry Smith PC_HYPRE *jac = (PC_HYPRE*)pc->data; 148d2128fa2SBarry Smith 149d2128fa2SBarry Smith PetscFunctionBegin; 150d2128fa2SBarry Smith *hsolver = jac->hsolver; 151d2128fa2SBarry Smith PetscFunctionReturn(0); 152d2128fa2SBarry Smith } 15316d9e3a6SLisandro Dalcin 154fd2dd295SFande Kong /* 1558a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1568a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1578a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 158fd2dd295SFande Kong */ 159fd2dd295SFande Kong static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt *nlevels,Mat *operators[]) 1608a2c336bSFande Kong { 1618a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1628a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1638a2c336bSFande Kong PetscInt num_levels,l; 1648a2c336bSFande Kong Mat *mattmp; 1658a2c336bSFande Kong hypre_ParCSRMatrix **A_array; 1668a2c336bSFande Kong 1678a2c336bSFande Kong PetscFunctionBegin; 1689566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type,"boomeramg",&same)); 1695f80ce2aSJacob Faibussowitsch PetscCheck(same,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG "); 1708a2c336bSFande Kong num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver)); 1719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels,&mattmp)); 1728a2c336bSFande Kong A_array = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver)); 1738a2c336bSFande Kong for (l=1; l<num_levels; l++) { 1749566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l]))); 1758a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 1768a2c336bSFande Kong A_array[l] = NULL; 1778a2c336bSFande Kong } 1788a2c336bSFande Kong *nlevels = num_levels; 1798a2c336bSFande Kong *operators = mattmp; 1808a2c336bSFande Kong PetscFunctionReturn(0); 1818a2c336bSFande Kong } 1828a2c336bSFande Kong 183fd2dd295SFande Kong /* 1848a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix 1858a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine. 1868a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function. 187fd2dd295SFande Kong */ 188fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[]) 1898a2c336bSFande Kong { 1908a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1918a2c336bSFande Kong PetscBool same = PETSC_FALSE; 1928a2c336bSFande Kong PetscInt num_levels,l; 1938a2c336bSFande Kong Mat *mattmp; 1948a2c336bSFande Kong hypre_ParCSRMatrix **P_array; 1958a2c336bSFande Kong 1968a2c336bSFande Kong PetscFunctionBegin; 1979566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type,"boomeramg",&same)); 1985f80ce2aSJacob Faibussowitsch PetscCheck(same,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG "); 1998a2c336bSFande Kong num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver)); 2009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels,&mattmp)); 2018a2c336bSFande Kong P_array = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver)); 2028a2c336bSFande Kong for (l=1; l<num_levels; l++) { 2039566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1]))); 2048a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */ 2058a2c336bSFande Kong P_array[num_levels-1-l] = NULL; 2068a2c336bSFande Kong } 2078a2c336bSFande Kong *nlevels = num_levels; 2088a2c336bSFande Kong *interpolations = mattmp; 2098a2c336bSFande Kong PetscFunctionReturn(0); 2108a2c336bSFande Kong } 2118a2c336bSFande Kong 212ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */ 213ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc) 214ce6a8a0dSJed Brown { 215ce6a8a0dSJed Brown PC_HYPRE *jac = (PC_HYPRE*)pc->data; 216ce6a8a0dSJed Brown PetscInt i; 217ce6a8a0dSJed Brown 2189d678128SJed Brown PetscFunctionBegin; 219ce6a8a0dSJed Brown for (i=0; i<jac->n_hmnull; i++) { 2209566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->hmnull[i])); 221ce6a8a0dSJed Brown } 2229566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hmnull)); 2239566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->phmnull)); 2249566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->hmnull_constant)); 2259d678128SJed Brown jac->n_hmnull = 0; 226ce6a8a0dSJed Brown PetscFunctionReturn(0); 227ce6a8a0dSJed Brown } 228ce6a8a0dSJed Brown 22916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc) 23016d9e3a6SLisandro Dalcin { 23116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 23249a781f5SStefano Zampini Mat_HYPRE *hjac; 23316d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 23416d9e3a6SLisandro Dalcin HYPRE_ParVector bv,xv; 23549a781f5SStefano Zampini PetscBool ishypre; 23616d9e3a6SLisandro Dalcin 23716d9e3a6SLisandro Dalcin PetscFunctionBegin; 23816d9e3a6SLisandro Dalcin if (!jac->hypre_type) { 2399566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType(pc,"boomeramg")); 24016d9e3a6SLisandro Dalcin } 2415f5c5b43SBarry Smith 2429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre)); 24349a781f5SStefano Zampini if (!ishypre) { 2449566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 2459566063dSJacob Faibussowitsch PetscCall(MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat)); 2469566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hpmat)); 24749a781f5SStefano Zampini } else { 2489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc->pmat)); 2499566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 25049a781f5SStefano Zampini jac->hpmat = pc->pmat; 25116d9e3a6SLisandro Dalcin } 2526ea7df73SStefano Zampini /* allow debug */ 2539566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(jac->hpmat,NULL,"-pc_hypre_mat_view")); 25449a781f5SStefano Zampini hjac = (Mat_HYPRE*)(jac->hpmat->data); 2555f5c5b43SBarry Smith 25616d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 25716d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 2585272c319SBarry Smith MatNullSpace mnull; 2595272c319SBarry Smith PetscBool has_const; 26049a781f5SStefano Zampini PetscInt bs,nvec,i; 2615272c319SBarry Smith const Vec *vecs; 2625272c319SBarry Smith 2639566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat,&bs)); 264792fecdfSBarry Smith if (bs > 1) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs); 2659566063dSJacob Faibussowitsch PetscCall(MatGetNearNullSpace(pc->mat, &mnull)); 2665272c319SBarry Smith if (mnull) { 2679566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 2689566063dSJacob Faibussowitsch PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs)); 2699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec+1,&jac->hmnull)); 2709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec+1,&jac->phmnull)); 2715272c319SBarry Smith for (i=0; i<nvec; i++) { 2729566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map,&jac->hmnull[i])); 2739566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(vecs[i],jac->hmnull[i])); 274792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->hmnull[i]->ij,(void**)&jac->phmnull[i]); 2755272c319SBarry Smith } 2765272c319SBarry Smith if (has_const) { 2779566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL)); 2789566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hmnull_constant)); 2799566063dSJacob Faibussowitsch PetscCall(VecSet(jac->hmnull_constant,1)); 2809566063dSJacob Faibussowitsch PetscCall(VecNormalize(jac->hmnull_constant,NULL)); 2819566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map,&jac->hmnull[nvec])); 2829566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant,jac->hmnull[nvec])); 283792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->hmnull[nvec]->ij,(void**)&jac->phmnull[nvec]); 2845272c319SBarry Smith nvec++; 2855272c319SBarry Smith } 286792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVectors,jac->hsolver,nvec,jac->phmnull); 2875272c319SBarry Smith jac->n_hmnull = nvec; 2885272c319SBarry Smith } 2894cb006feSStefano Zampini } 290863406b8SStefano Zampini 2914cb006feSStefano Zampini /* special case for AMS */ 2924cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 2935ac14e1cSStefano Zampini Mat_HYPRE *hm; 2945ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 2956bf688a0SCe Qin if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 2966bf688a0SCe 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"); 2976bf688a0SCe Qin } 2985ac14e1cSStefano Zampini if (jac->dim) { 299792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDimension,jac->hsolver,jac->dim); 3005ac14e1cSStefano Zampini } 3015ac14e1cSStefano Zampini if (jac->constants[0]) { 3025ac14e1cSStefano Zampini HYPRE_ParVector ozz,zoz,zzo = NULL; 303792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[0]->ij,(void**)(&ozz)); 304792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[1]->ij,(void**)(&zoz)); 3055ac14e1cSStefano Zampini if (jac->constants[2]) { 306792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[2]->ij,(void**)(&zzo)); 3075ac14e1cSStefano Zampini } 308792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetEdgeConstantVectors,jac->hsolver,ozz,zoz,zzo); 3095ac14e1cSStefano Zampini } 3105ac14e1cSStefano Zampini if (jac->coords[0]) { 3115ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3125ac14e1cSStefano Zampini coords[0] = NULL; 3135ac14e1cSStefano Zampini coords[1] = NULL; 3145ac14e1cSStefano Zampini coords[2] = NULL; 315792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0])); 316792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1])); 317792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2])); 318792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]); 3195ac14e1cSStefano Zampini } 3205f80ce2aSJacob Faibussowitsch PetscCheck(jac->G,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3215ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->G->data); 322792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 323792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDiscreteGradient,jac->hsolver,parcsr); 3245ac14e1cSStefano Zampini if (jac->alpha_Poisson) { 3255ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->alpha_Poisson->data); 326792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 327792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaPoissonMatrix,jac->hsolver,parcsr); 3285ac14e1cSStefano Zampini } 3295ac14e1cSStefano Zampini if (jac->ams_beta_is_zero) { 330792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,NULL); 3315ac14e1cSStefano Zampini } else if (jac->beta_Poisson) { 3325ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->beta_Poisson->data); 333792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 334792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,parcsr); 3355ac14e1cSStefano Zampini } 3366bf688a0SCe Qin if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) { 3376bf688a0SCe Qin PetscInt i; 3386bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3396bf688a0SCe Qin if (jac->ND_PiFull) { 3406bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->ND_PiFull->data); 341792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsrfull)); 3426bf688a0SCe Qin } else { 3436bf688a0SCe Qin nd_parcsrfull = NULL; 3446bf688a0SCe Qin } 3456bf688a0SCe Qin for (i=0;i<3;++i) { 3466bf688a0SCe Qin if (jac->ND_Pi[i]) { 3476bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data); 348792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i])); 3496bf688a0SCe Qin } else { 3506bf688a0SCe Qin nd_parcsr[i] = NULL; 3516bf688a0SCe Qin } 3526bf688a0SCe Qin } 353792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetInterpolations,jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]); 3546bf688a0SCe Qin } 3554cb006feSStefano Zampini } 356863406b8SStefano Zampini /* special case for ADS */ 357863406b8SStefano Zampini if (jac->setup == HYPRE_ADSSetup) { 3585ac14e1cSStefano Zampini Mat_HYPRE *hm; 3595ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 3606bf688a0SCe Qin if (!jac->coords[0] && !((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])))) { 3616bf688a0SCe Qin SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations"); 3626bf688a0SCe Qin } 3637827d75bSBarry 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"); 3645f80ce2aSJacob Faibussowitsch PetscCheck(jac->G,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 3655f80ce2aSJacob Faibussowitsch PetscCheck(jac->C,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient"); 3665ac14e1cSStefano Zampini if (jac->coords[0]) { 3675ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 3685ac14e1cSStefano Zampini coords[0] = NULL; 3695ac14e1cSStefano Zampini coords[1] = NULL; 3705ac14e1cSStefano Zampini coords[2] = NULL; 371792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0])); 372792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1])); 373792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2])); 374792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]); 3755ac14e1cSStefano Zampini } 3765ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->G->data); 377792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 378792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteGradient,jac->hsolver,parcsr); 3795ac14e1cSStefano Zampini hm = (Mat_HYPRE*)(jac->C->data); 380792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr)); 381792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteCurl,jac->hsolver,parcsr); 3826bf688a0SCe Qin if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 3836bf688a0SCe Qin PetscInt i; 3846bf688a0SCe Qin HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3]; 3856bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 3866bf688a0SCe Qin if (jac->RT_PiFull) { 3876bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->RT_PiFull->data); 388792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&rt_parcsrfull)); 3896bf688a0SCe Qin } else { 3906bf688a0SCe Qin rt_parcsrfull = NULL; 3916bf688a0SCe Qin } 3926bf688a0SCe Qin for (i=0;i<3;++i) { 3936bf688a0SCe Qin if (jac->RT_Pi[i]) { 3946bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data); 395792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&rt_parcsr[i])); 3966bf688a0SCe Qin } else { 3976bf688a0SCe Qin rt_parcsr[i] = NULL; 3986bf688a0SCe Qin } 3996bf688a0SCe Qin } 4006bf688a0SCe Qin if (jac->ND_PiFull) { 4016bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->ND_PiFull->data); 402792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsrfull)); 4036bf688a0SCe Qin } else { 4046bf688a0SCe Qin nd_parcsrfull = NULL; 4056bf688a0SCe Qin } 4066bf688a0SCe Qin for (i=0;i<3;++i) { 4076bf688a0SCe Qin if (jac->ND_Pi[i]) { 4086bf688a0SCe Qin hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data); 409792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i])); 4106bf688a0SCe Qin } else { 4116bf688a0SCe Qin nd_parcsr[i] = NULL; 4126bf688a0SCe Qin } 4136bf688a0SCe Qin } 414792fecdfSBarry 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]); 4156bf688a0SCe Qin } 416863406b8SStefano Zampini } 417792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat); 418792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&bv); 419792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&xv); 420792fecdfSBarry Smith PetscCallExternal(jac->setup,jac->hsolver,hmat,bv,xv); 42116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 42216d9e3a6SLisandro Dalcin } 42316d9e3a6SLisandro Dalcin 42416d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x) 42516d9e3a6SLisandro Dalcin { 42616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 42749a781f5SStefano Zampini Mat_HYPRE *hjac = (Mat_HYPRE*)(jac->hpmat->data); 42816d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 42916d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 43016d9e3a6SLisandro Dalcin 43116d9e3a6SLisandro Dalcin PetscFunctionBegin; 4329566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 4339566063dSJacob Faibussowitsch if (!jac->applyrichardson) PetscCall(VecSet(x,0.0)); 4349566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b,b)); 4359566063dSJacob Faibussowitsch if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x,x)); 4369566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x,x)); 437792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat); 438792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv); 439792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv); 440*e77caa6dSBarry Smith PetscStackCallExternalVoid("Hypre solve",do { 4415f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv); 4425f80ce2aSJacob Faibussowitsch if (hierr) { 4435f80ce2aSJacob Faibussowitsch PetscCheck(hierr == HYPRE_ERROR_CONV,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",(int)hierr); 4445f80ce2aSJacob Faibussowitsch hypre__global_error = 0; 4455f80ce2aSJacob Faibussowitsch } 4465f80ce2aSJacob Faibussowitsch } while (0)); 44716d9e3a6SLisandro Dalcin 44823df4f25SStefano Zampini if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) { 449792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSProjectOutGradients,jac->hsolver,jxv); 45021df291bSStefano Zampini } 4519566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 4529566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 45316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 45416d9e3a6SLisandro Dalcin } 45516d9e3a6SLisandro Dalcin 4568695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc) 4578695de01SBarry Smith { 4588695de01SBarry Smith PC_HYPRE *jac = (PC_HYPRE*)pc->data; 4598695de01SBarry Smith 4608695de01SBarry Smith PetscFunctionBegin; 4619566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 4629566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 4639566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 4649566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 4659566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 4669566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 4679566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[0])); 4689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[1])); 4699566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[2])); 4709566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 4719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[0])); 4729566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[1])); 4739566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[2])); 4749566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 4759566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 4769566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 4779566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 4789566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 4799566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 4809566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 4815ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 4825ac14e1cSStefano Zampini jac->dim = 0; 4838695de01SBarry Smith PetscFunctionReturn(0); 4848695de01SBarry Smith } 4858695de01SBarry Smith 48616d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc) 48716d9e3a6SLisandro Dalcin { 48816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 48916d9e3a6SLisandro Dalcin 49016d9e3a6SLisandro Dalcin PetscFunctionBegin; 4919566063dSJacob Faibussowitsch PetscCall(PCReset_HYPRE(pc)); 492792fecdfSBarry Smith if (jac->destroy) PetscCallExternal(jac->destroy,jac->hsolver); 4939566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 494db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 4959566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->spgemm_type)); 496db6f9c32SMark Adams #endif 4979566063dSJacob Faibussowitsch if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre)); 4989566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 49916d9e3a6SLisandro Dalcin 5009566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc,0)); 5019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL)); 5029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL)); 5039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL)); 5049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL)); 5059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL)); 5069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL)); 5079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL)); 5082e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",NULL)); 5099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL)); 5109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL)); 5119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",NULL)); 5129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",NULL)); 5132e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL)); 51416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 51516d9e3a6SLisandro Dalcin } 51616d9e3a6SLisandro Dalcin 51716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 5184416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc) 51916d9e3a6SLisandro Dalcin { 52016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 521ace3abfcSBarry Smith PetscBool flag; 52216d9e3a6SLisandro Dalcin 52316d9e3a6SLisandro Dalcin PetscFunctionBegin; 524d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE Pilut Options"); 5259566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag)); 526792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetMaxIter,jac->hsolver,jac->maxiter); 5279566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag)); 528792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetDropTolerance,jac->hsolver,jac->tol); 5299566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag)); 530792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetFactorRowSize,jac->hsolver,jac->factorrowsize); 531d0609cedSBarry Smith PetscOptionsHeadEnd(); 53216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 53316d9e3a6SLisandro Dalcin } 53416d9e3a6SLisandro Dalcin 53516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer) 53616d9e3a6SLisandro Dalcin { 53716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 538ace3abfcSBarry Smith PetscBool iascii; 53916d9e3a6SLisandro Dalcin 54016d9e3a6SLisandro Dalcin PetscFunctionBegin; 5419566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 54216d9e3a6SLisandro Dalcin if (iascii) { 5439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE Pilut preconditioning\n")); 54416d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 54563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," maximum number of iterations %" PetscInt_FMT "\n",jac->maxiter)); 54616d9e3a6SLisandro Dalcin } else { 5479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," default maximum number of iterations \n")); 54816d9e3a6SLisandro Dalcin } 54916d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 5509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," drop tolerance %g\n",(double)jac->tol)); 55116d9e3a6SLisandro Dalcin } else { 5529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," default drop tolerance \n")); 55316d9e3a6SLisandro Dalcin } 55416d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 55563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," factor row size %" PetscInt_FMT "\n",jac->factorrowsize)); 55616d9e3a6SLisandro Dalcin } else { 5579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," default factor row size \n")); 55816d9e3a6SLisandro Dalcin } 55916d9e3a6SLisandro Dalcin } 56016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 56116d9e3a6SLisandro Dalcin } 56216d9e3a6SLisandro Dalcin 56316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 564db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc) 565db966c6cSHong Zhang { 566db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE*)pc->data; 5678bf83915SBarry Smith PetscBool flag,eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE; 568db966c6cSHong Zhang 569db966c6cSHong Zhang PetscFunctionBegin; 570d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE Euclid Options"); 5719566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag)); 572792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_EuclidSetLevel,jac->hsolver,jac->eu_level); 5738bf83915SBarry Smith 5749566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_euclid_droptolerance","Drop tolerance for ILU(k) in Euclid","None",jac->eu_droptolerance,&jac->eu_droptolerance,&flag)); 5758bf83915SBarry Smith if (flag) { 5768bf83915SBarry Smith PetscMPIInt size; 5778bf83915SBarry Smith 5789566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size)); 5797827d75bSBarry Smith PetscCheck(size == 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance"); 580792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetILUT,jac->hsolver,jac->eu_droptolerance); 5818bf83915SBarry Smith } 5828bf83915SBarry Smith 5839566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj,&eu_bj,&flag)); 5848bf83915SBarry Smith if (flag) { 5858bf83915SBarry Smith jac->eu_bj = eu_bj ? 1 : 0; 586792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetBJ,jac->hsolver,jac->eu_bj); 5878bf83915SBarry Smith } 588d0609cedSBarry Smith PetscOptionsHeadEnd(); 589db966c6cSHong Zhang PetscFunctionReturn(0); 590db966c6cSHong Zhang } 591db966c6cSHong Zhang 592db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer) 593db966c6cSHong Zhang { 594db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE*)pc->data; 595db966c6cSHong Zhang PetscBool iascii; 596db966c6cSHong Zhang 597db966c6cSHong Zhang PetscFunctionBegin; 5989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 599db966c6cSHong Zhang if (iascii) { 6009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE Euclid preconditioning\n")); 601db966c6cSHong Zhang if (jac->eu_level != PETSC_DEFAULT) { 60263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," factorization levels %" PetscInt_FMT "\n",jac->eu_level)); 603db966c6cSHong Zhang } else { 6049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," default factorization levels \n")); 605db966c6cSHong Zhang } 6069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," drop tolerance %g\n",(double)jac->eu_droptolerance)); 60763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," use Block-Jacobi? %" PetscInt_FMT "\n",jac->eu_bj)); 608db966c6cSHong Zhang } 609db966c6cSHong Zhang PetscFunctionReturn(0); 610db966c6cSHong Zhang } 611db966c6cSHong Zhang 612db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/ 61316d9e3a6SLisandro Dalcin 61416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x) 61516d9e3a6SLisandro Dalcin { 61616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 61749a781f5SStefano Zampini Mat_HYPRE *hjac = (Mat_HYPRE*)(jac->hpmat->data); 61816d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 61916d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 62016d9e3a6SLisandro Dalcin 62116d9e3a6SLisandro Dalcin PetscFunctionBegin; 6229566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 6239566063dSJacob Faibussowitsch PetscCall(VecSet(x,0.0)); 6249566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->x,b)); 6259566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->b,x)); 62616d9e3a6SLisandro Dalcin 627792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat); 628792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv); 629792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv); 63016d9e3a6SLisandro Dalcin 631*e77caa6dSBarry Smith PetscStackCallExternalVoid("Hypre Transpose solve",do { 6325f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv); 6335f80ce2aSJacob Faibussowitsch if (hierr) { 63416d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 6355f80ce2aSJacob Faibussowitsch PetscCheck(hierr == 1,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",(int)hierr); 6365f80ce2aSJacob Faibussowitsch hypre__global_error = 0; 6375f80ce2aSJacob Faibussowitsch } 6385f80ce2aSJacob Faibussowitsch } while (0)); 63916d9e3a6SLisandro Dalcin 6409566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 6419566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 64216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 64316d9e3a6SLisandro Dalcin } 64416d9e3a6SLisandro Dalcin 645db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc,const char name[]) 646db6f9c32SMark Adams { 647db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE*)pc->data; 648db6f9c32SMark Adams PetscBool flag; 649db6f9c32SMark Adams 650db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 651db6f9c32SMark Adams PetscFunctionBegin; 652db6f9c32SMark Adams if (jac->spgemm_type) { 6539566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->spgemm_type,name,&flag)); 65428b400f6SJacob Faibussowitsch PetscCheck(flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE SpGEMM (really we can)"); 655db6f9c32SMark Adams PetscFunctionReturn(0); 656db6f9c32SMark Adams } else { 6579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->spgemm_type)); 658db6f9c32SMark Adams } 6599566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("cusparse",jac->spgemm_type,&flag)); 660db6f9c32SMark Adams if (flag) { 661792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse,1); 662db6f9c32SMark Adams PetscFunctionReturn(0); 663db6f9c32SMark Adams } 6649566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("hypre",jac->spgemm_type,&flag)); 665db6f9c32SMark Adams if (flag) { 666792fecdfSBarry Smith PetscCallExternal(HYPRE_SetSpGemmUseCusparse,0); 667db6f9c32SMark Adams PetscFunctionReturn(0); 668db6f9c32SMark Adams } 669db6f9c32SMark Adams jac->spgemm_type = NULL; 67098921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE SpGEM type %s; Choices are cusparse, hypre",name); 671db6f9c32SMark Adams #endif 672db6f9c32SMark Adams } 673db6f9c32SMark Adams 674db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[]) 675db6f9c32SMark Adams { 676db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE*)pc->data; 677db6f9c32SMark Adams 678db6f9c32SMark Adams PetscFunctionBegin; 679db6f9c32SMark Adams PetscValidHeaderSpecific(pc,PC_CLASSID,1); 680db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 681db6f9c32SMark Adams *spgemm = jac->spgemm_type; 682db6f9c32SMark Adams #endif 683db6f9c32SMark Adams PetscFunctionReturn(0); 684db6f9c32SMark Adams } 685db6f9c32SMark Adams 68616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"","V","W"}; 6870f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"}; 68816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"}; 68965de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 6906a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[] = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"}; 69165de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[] = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi", 69265de4495SJed Brown "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi", 69365de4495SJed Brown "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination", 6947b7fa87dSPierre Jolivet "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */, 69565de4495SJed Brown "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"}; 6960f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[] = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i", 697589dcaf0SStefano Zampini "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1", 698589dcaf0SStefano Zampini "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"}; 6994416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc) 70016d9e3a6SLisandro Dalcin { 70116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 70222e51d31SStefano Zampini PetscInt bs,n,indx,level; 703ace3abfcSBarry Smith PetscBool flg, tmp_truth; 70416d9e3a6SLisandro Dalcin double tmpdbl, twodbl[2]; 705589dcaf0SStefano Zampini const char *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"}; 706db6f9c32SMark Adams const char *PCHYPRESpgemmTypes[] = {"cusparse","hypre"}; 70716d9e3a6SLisandro Dalcin 70816d9e3a6SLisandro Dalcin PetscFunctionBegin; 709d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE BoomerAMG Options"); 7109566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg)); 71116d9e3a6SLisandro Dalcin if (flg) { 7124336a9eeSBarry Smith jac->cycletype = indx+1; 713792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype); 71416d9e3a6SLisandro Dalcin } 7159566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg)); 71616d9e3a6SLisandro Dalcin if (flg) { 71763a3b9bcSJacob Faibussowitsch PetscCheck(jac->maxlevels >= 2,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %" PetscInt_FMT " must be at least two",jac->maxlevels); 718792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels); 71916d9e3a6SLisandro Dalcin } 7209566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg)); 72116d9e3a6SLisandro Dalcin if (flg) { 72263a3b9bcSJacob Faibussowitsch PetscCheck(jac->maxiter >= 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %" PetscInt_FMT " must be at least one",jac->maxiter); 723792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter); 72416d9e3a6SLisandro Dalcin } 7259566063dSJacob 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)); 72616d9e3a6SLisandro Dalcin if (flg) { 72708401ef6SPierre 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); 728792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol); 72916d9e3a6SLisandro Dalcin } 73022e51d31SStefano Zampini bs = 1; 73122e51d31SStefano Zampini if (pc->pmat) { 7329566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat,&bs)); 73322e51d31SStefano Zampini } 7349566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg)); 73522e51d31SStefano Zampini if (flg) { 736792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs); 73722e51d31SStefano Zampini } 73816d9e3a6SLisandro Dalcin 7399566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg)); 74016d9e3a6SLisandro Dalcin if (flg) { 74108401ef6SPierre 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); 742792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor); 74316d9e3a6SLisandro Dalcin } 74416d9e3a6SLisandro Dalcin 7459566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_P_max","Max elements per row for interpolation operator (0=unlimited)","None",jac->pmax,&jac->pmax,&flg)); 7460f1074feSSatish Balay if (flg) { 74763a3b9bcSJacob 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); 748792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax); 7490f1074feSSatish Balay } 7500f1074feSSatish Balay 7519566063dSJacob 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)); 752792fecdfSBarry Smith if (flg) PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl); 7530f1074feSSatish Balay 7549566063dSJacob 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)); 7550f1074feSSatish Balay if (flg) { 75663a3b9bcSJacob 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); 757792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths); 7580f1074feSSatish Balay } 7590f1074feSSatish Balay 7609566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg)); 76116d9e3a6SLisandro Dalcin if (flg) { 76208401ef6SPierre 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); 763792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold); 76416d9e3a6SLisandro Dalcin } 7659566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg)); 76616d9e3a6SLisandro Dalcin if (flg) { 76708401ef6SPierre 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); 76808401ef6SPierre 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); 769792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum); 77016d9e3a6SLisandro Dalcin } 77116d9e3a6SLisandro Dalcin 77216d9e3a6SLisandro Dalcin /* Grid sweeps */ 7739566063dSJacob 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)); 77416d9e3a6SLisandro Dalcin if (flg) { 775792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver,indx); 77616d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 77716d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 7780f1074feSSatish Balay jac->gridsweeps[1] = indx; 7790f1074feSSatish Balay /*defaults coarse to 1 */ 7800f1074feSSatish Balay jac->gridsweeps[2] = 1; 78116d9e3a6SLisandro Dalcin } 7829566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen","Use a nodal based coarsening 1-6","HYPRE_BoomerAMGSetNodal",jac->nodal_coarsening,&jac->nodal_coarsening,&flg)); 7835272c319SBarry Smith if (flg) { 784792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNodal,jac->hsolver,jac->nodal_coarsening); 7855272c319SBarry Smith } 7869566063dSJacob 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)); 78722e51d31SStefano Zampini if (flg) { 788792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNodalDiag,jac->hsolver,jac->nodal_coarsening_diag); 78922e51d31SStefano Zampini } 7909566063dSJacob 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)); 7915272c319SBarry Smith if (flg) { 792792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVecVariant,jac->hsolver,jac->vec_interp_variant); 7935272c319SBarry Smith } 7949566063dSJacob 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)); 79522e51d31SStefano Zampini if (flg) { 796792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVecQMax,jac->hsolver,jac->vec_interp_qmax); 79722e51d31SStefano Zampini } 7989566063dSJacob 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)); 79922e51d31SStefano Zampini if (flg) { 800792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothInterpVectors,jac->hsolver,jac->vec_interp_smooth); 80122e51d31SStefano Zampini } 8029566063dSJacob 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)); 80322e51d31SStefano Zampini if (flg) { 804792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpRefine,jac->hsolver,jac->interp_refine); 80522e51d31SStefano Zampini } 8069566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg)); 80716d9e3a6SLisandro Dalcin if (flg) { 808792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 1); 8090f1074feSSatish Balay jac->gridsweeps[0] = indx; 81016d9e3a6SLisandro Dalcin } 8119566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg)); 81216d9e3a6SLisandro Dalcin if (flg) { 813792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 2); 8140f1074feSSatish Balay jac->gridsweeps[1] = indx; 81516d9e3a6SLisandro Dalcin } 8169566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg)); 81716d9e3a6SLisandro Dalcin if (flg) { 818792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 3); 8190f1074feSSatish Balay jac->gridsweeps[2] = indx; 82016d9e3a6SLisandro Dalcin } 82116d9e3a6SLisandro Dalcin 8226a251517SEike Mueller /* Smooth type */ 823dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg)); 8246a251517SEike Mueller if (flg) { 8256a251517SEike Mueller jac->smoothtype = indx; 826792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,indx+6); 8278131ecf7SEike Mueller jac->smoothnumlevels = 25; 828792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,25); 8298131ecf7SEike Mueller } 8308131ecf7SEike Mueller 8318131ecf7SEike Mueller /* Number of smoothing levels */ 8329566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels","Number of levels on which more complex smoothers are used","None",25,&indx,&flg)); 8338131ecf7SEike Mueller if (flg && (jac->smoothtype != -1)) { 8348131ecf7SEike Mueller jac->smoothnumlevels = indx; 835792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,indx); 8366a251517SEike Mueller } 8376a251517SEike Mueller 8381810e44eSEike Mueller /* Number of levels for ILU(k) for Euclid */ 8399566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg)); 8401810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8411810e44eSEike Mueller jac->eu_level = indx; 842792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,indx); 8431810e44eSEike Mueller } 8441810e44eSEike Mueller 8451810e44eSEike Mueller /* Filter for ILU(k) for Euclid */ 8461810e44eSEike Mueller double droptolerance; 8479566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg)); 8481810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8491810e44eSEike Mueller jac->eu_droptolerance = droptolerance; 850792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,droptolerance); 8511810e44eSEike Mueller } 8521810e44eSEike Mueller 8531810e44eSEike Mueller /* Use Block Jacobi ILUT for Euclid */ 8549566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg)); 8551810e44eSEike Mueller if (flg && (jac->smoothtype == 3)) { 8561810e44eSEike Mueller jac->eu_bj = tmp_truth; 857792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuBJ,jac->hsolver,jac->eu_bj); 8581810e44eSEike Mueller } 8591810e44eSEike Mueller 86016d9e3a6SLisandro Dalcin /* Relax type */ 861dd39110bSPierre 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)); 86216d9e3a6SLisandro Dalcin if (flg) { 8630f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 864792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, indx); 8650f1074feSSatish Balay /* by default, coarse type set to 9 */ 8660f1074feSSatish Balay jac->relaxtype[2] = 9; 867792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, 9, 3); 86816d9e3a6SLisandro Dalcin } 869dd39110bSPierre 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)); 87016d9e3a6SLisandro Dalcin if (flg) { 87116d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 872792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 1); 87316d9e3a6SLisandro Dalcin } 874dd39110bSPierre 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)); 87516d9e3a6SLisandro Dalcin if (flg) { 8760f1074feSSatish Balay jac->relaxtype[1] = indx; 877792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 2); 87816d9e3a6SLisandro Dalcin } 879dd39110bSPierre 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)); 88016d9e3a6SLisandro Dalcin if (flg) { 8810f1074feSSatish Balay jac->relaxtype[2] = indx; 882792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 3); 88316d9e3a6SLisandro Dalcin } 88416d9e3a6SLisandro Dalcin 88516d9e3a6SLisandro Dalcin /* Relaxation Weight */ 8869566063dSJacob 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)); 88716d9e3a6SLisandro Dalcin if (flg) { 888792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxWt,jac->hsolver,tmpdbl); 88916d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 89016d9e3a6SLisandro Dalcin } 89116d9e3a6SLisandro Dalcin 89216d9e3a6SLisandro Dalcin n = 2; 89316d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 8949566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level","Set the relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg)); 89516d9e3a6SLisandro Dalcin if (flg) { 89616d9e3a6SLisandro Dalcin if (n == 2) { 89716d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 898792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelRelaxWt,jac->hsolver,twodbl[0],indx); 89963a3b9bcSJacob 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); 90016d9e3a6SLisandro Dalcin } 90116d9e3a6SLisandro Dalcin 90216d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 9039566063dSJacob 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)); 90416d9e3a6SLisandro Dalcin if (flg) { 905792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOuterWt,jac->hsolver, tmpdbl); 90616d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 90716d9e3a6SLisandro Dalcin } 90816d9e3a6SLisandro Dalcin 90916d9e3a6SLisandro Dalcin n = 2; 91016d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 9119566063dSJacob 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)); 91216d9e3a6SLisandro Dalcin if (flg) { 91316d9e3a6SLisandro Dalcin if (n == 2) { 91416d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 915792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelOuterWt,jac->hsolver, twodbl[0], indx); 91663a3b9bcSJacob 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); 91716d9e3a6SLisandro Dalcin } 91816d9e3a6SLisandro Dalcin 91916d9e3a6SLisandro Dalcin /* the Relax Order */ 9209566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg)); 92116d9e3a6SLisandro Dalcin 9228afaa268SBarry Smith if (flg && tmp_truth) { 92316d9e3a6SLisandro Dalcin jac->relaxorder = 0; 924792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder); 92516d9e3a6SLisandro Dalcin } 926dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg)); 92716d9e3a6SLisandro Dalcin if (flg) { 92816d9e3a6SLisandro Dalcin jac->measuretype = indx; 929792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype); 93016d9e3a6SLisandro Dalcin } 9310f1074feSSatish Balay /* update list length 3/07 */ 932dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg)); 93316d9e3a6SLisandro Dalcin if (flg) { 93416d9e3a6SLisandro Dalcin jac->coarsentype = indx; 935792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype); 93616d9e3a6SLisandro Dalcin } 9370f1074feSSatish Balay 9389566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg)); 939589dcaf0SStefano Zampini if (flg) { 940792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc); 941589dcaf0SStefano Zampini } 9429566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg)); 943589dcaf0SStefano Zampini if (flg) { 944792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc); 945589dcaf0SStefano Zampini } 946db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 947db6f9c32SMark Adams // global parameter but is closely associated with BoomerAMG 948dd39110bSPierre 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)); 949db6f9c32SMark Adams if (!flg) indx = 0; 9509566063dSJacob Faibussowitsch PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc,PCHYPRESpgemmTypes[indx])); 951db6f9c32SMark Adams #endif 952589dcaf0SStefano Zampini /* AIR */ 953589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0) 9549566063dSJacob 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)); 955792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype); 956589dcaf0SStefano Zampini if (jac->Rtype) { 957589dcaf0SStefano 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 */ 958589dcaf0SStefano Zampini 9599566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR","Threshold for R","None",jac->Rstrongthreshold,&jac->Rstrongthreshold,NULL)); 960792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold); 961589dcaf0SStefano Zampini 9629566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR","Filter threshold for R","None",jac->Rfilterthreshold,&jac->Rfilterthreshold,NULL)); 963792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold); 964589dcaf0SStefano Zampini 9659566063dSJacob 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)); 966792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol); 967589dcaf0SStefano Zampini 9689566063dSJacob 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)); 969792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype); 970589dcaf0SStefano Zampini } 971589dcaf0SStefano Zampini #endif 972589dcaf0SStefano Zampini 973ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9,9,9) 97463a3b9bcSJacob 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); 975ecae95adSPierre Jolivet #endif 976ecae95adSPierre Jolivet 9770f1074feSSatish Balay /* new 3/07 */ 978dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg)); 979589dcaf0SStefano Zampini if (flg || jac->Rtype) { 980589dcaf0SStefano Zampini if (flg) jac->interptype = indx; 981792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype); 9820f1074feSSatish Balay } 9830f1074feSSatish Balay 9849566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg)); 98516d9e3a6SLisandro Dalcin if (flg) { 986b96a4a96SBarry Smith level = 3; 9879566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL)); 9882fa5cd67SKarl Rupp 989b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 990792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel,jac->hsolver,level); 9912ae77aedSBarry Smith } 9922ae77aedSBarry Smith 9939566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg)); 9942ae77aedSBarry Smith if (flg) { 995b96a4a96SBarry Smith level = 3; 9969566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL)); 9972fa5cd67SKarl Rupp 998b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 999792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDebugFlag,jac->hsolver,level); 100016d9e3a6SLisandro Dalcin } 10018f87f92bSBarry Smith 10029566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg)); 10038f87f92bSBarry Smith if (flg && tmp_truth) { 10048f87f92bSBarry Smith PetscInt tmp_int; 10059566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg)); 10068f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 1007792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,6); 1008792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDomainType,jac->hsolver,1); 1009792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOverlap,jac->hsolver,0); 1010792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,jac->nodal_relax_levels); 10118f87f92bSBarry Smith } 10128f87f92bSBarry Smith 10139566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL)); 1014792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0); 1015589dcaf0SStefano Zampini 1016589dcaf0SStefano Zampini /* options for ParaSails solvers */ 1017dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,PETSC_STATIC_ARRAY_LENGTH(symtlist),symtlist[0],&indx,&flg)); 1018589dcaf0SStefano Zampini if (flg) { 1019589dcaf0SStefano Zampini jac->symt = indx; 1020792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSym,jac->hsolver,jac->symt); 1021589dcaf0SStefano Zampini } 1022589dcaf0SStefano Zampini 1023d0609cedSBarry Smith PetscOptionsHeadEnd(); 102416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 102516d9e3a6SLisandro Dalcin } 102616d9e3a6SLisandro Dalcin 1027ace3abfcSBarry 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) 102816d9e3a6SLisandro Dalcin { 102916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 10302cf14000SStefano Zampini HYPRE_Int oits; 103116d9e3a6SLisandro Dalcin 103216d9e3a6SLisandro Dalcin PetscFunctionBegin; 10339566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 1034792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,its*jac->maxiter); 1035792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,rtol); 103616d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 10379566063dSJacob Faibussowitsch PetscCall(PCApply_HYPRE(pc,b,y)); 103816d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 1039792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGGetNumIterations,jac->hsolver,&oits); 10404d0a8057SBarry Smith *outits = oits; 10414d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 10424d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1043792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol); 1044792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter); 104516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 104616d9e3a6SLisandro Dalcin } 104716d9e3a6SLisandro Dalcin 104816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer) 104916d9e3a6SLisandro Dalcin { 105016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1051ace3abfcSBarry Smith PetscBool iascii; 105216d9e3a6SLisandro Dalcin 105316d9e3a6SLisandro Dalcin PetscFunctionBegin; 10549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 105516d9e3a6SLisandro Dalcin if (iascii) { 10569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG preconditioning\n")); 10579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype])); 105863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Maximum number of levels %" PetscInt_FMT "\n",jac->maxlevels)); 105963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Maximum number of iterations PER hypre call %" PetscInt_FMT "\n",jac->maxiter)); 10609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Convergence tolerance PER hypre call %g\n",(double)jac->tol)); 10619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Threshold for strong coupling %g\n",(double)jac->strongthreshold)); 10629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Interpolation truncation factor %g\n",(double)jac->truncfactor)); 106363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Interpolation: max elements per row %" PetscInt_FMT "\n",jac->pmax)); 106422e51d31SStefano Zampini if (jac->interp_refine) { 106563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n",jac->interp_refine)); 106622e51d31SStefano Zampini } 106763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Number of levels of aggressive coarsening %" PetscInt_FMT "\n",jac->agg_nl)); 106863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Number of paths for aggressive coarsening %" PetscInt_FMT "\n",jac->agg_num_paths)); 10690f1074feSSatish Balay 10709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Maximum row sums %g\n",(double)jac->maxrowsum)); 107116d9e3a6SLisandro Dalcin 107263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Sweeps down %" PetscInt_FMT "\n",jac->gridsweeps[0])); 107363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Sweeps up %" PetscInt_FMT "\n",jac->gridsweeps[1])); 107463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Sweeps on coarse %" PetscInt_FMT "\n",jac->gridsweeps[2])); 107516d9e3a6SLisandro Dalcin 10769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Relax down %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]])); 10779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Relax up %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]])); 10789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Relax on coarse %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]])); 107916d9e3a6SLisandro Dalcin 10809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Relax weight (all) %g\n",(double)jac->relaxweight)); 10819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Outer relax weight (all) %g\n",(double)jac->outerrelaxweight)); 108216d9e3a6SLisandro Dalcin 108316d9e3a6SLisandro Dalcin if (jac->relaxorder) { 10849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Using CF-relaxation\n")); 108516d9e3a6SLisandro Dalcin } else { 10869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Not using CF-relaxation\n")); 108716d9e3a6SLisandro Dalcin } 10886a251517SEike Mueller if (jac->smoothtype!=-1) { 10899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Smooth type %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype])); 109063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Smooth num levels %" PetscInt_FMT "\n",jac->smoothnumlevels)); 10917e352d70SEike Mueller } else { 10929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Not using more complex smoothers.\n")); 10931810e44eSEike Mueller } 10941810e44eSEike Mueller if (jac->smoothtype==3) { 109563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Euclid ILU(k) levels %" PetscInt_FMT "\n",jac->eu_level)); 10969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance)); 109763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n",jac->eu_bj)); 10986a251517SEike Mueller } 10999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Measure type %s\n",HYPREBoomerAMGMeasureType[jac->measuretype])); 11009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Coarsen type %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype])); 11019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Interpolation type %s\n",jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt")); 11025272c319SBarry Smith if (jac->nodal_coarsening) { 110363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n",jac->nodal_coarsening)); 11045272c319SBarry Smith } 11055272c319SBarry Smith if (jac->vec_interp_variant) { 110663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n",jac->vec_interp_variant)); 110763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n",jac->vec_interp_qmax)); 11089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth)); 11098f87f92bSBarry Smith } 11108f87f92bSBarry Smith if (jac->nodal_relax) { 111163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n",jac->nodal_relax_levels)); 11128f87f92bSBarry Smith } 1113db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0) 11149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," SpGEMM type %s\n",jac->spgemm_type)); 1115db6f9c32SMark Adams #endif 1116589dcaf0SStefano Zampini /* AIR */ 1117589dcaf0SStefano Zampini if (jac->Rtype) { 111863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Using approximate ideal restriction type %" PetscInt_FMT "\n",jac->Rtype)); 11199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Threshold for R %g\n",(double)jac->Rstrongthreshold)); 11209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Filter for R %g\n",(double)jac->Rfilterthreshold)); 11219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," A drop tolerance %g\n",(double)jac->Adroptol)); 112263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," A drop type %" PetscInt_FMT "\n",jac->Adroptype)); 1123589dcaf0SStefano Zampini } 112416d9e3a6SLisandro Dalcin } 112516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 112616d9e3a6SLisandro Dalcin } 112716d9e3a6SLisandro Dalcin 112816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 11294416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc) 113016d9e3a6SLisandro Dalcin { 113116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 11324ddd07fcSJed Brown PetscInt indx; 1133ace3abfcSBarry Smith PetscBool flag; 113416d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"}; 113516d9e3a6SLisandro Dalcin 113616d9e3a6SLisandro Dalcin PetscFunctionBegin; 1137d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE ParaSails Options"); 11389566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0)); 11399566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag)); 1140792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels); 114116d9e3a6SLisandro Dalcin 11429566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag)); 1143792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter); 114416d9e3a6SLisandro Dalcin 11459566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag)); 1146792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal); 114716d9e3a6SLisandro Dalcin 11489566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag)); 1149792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging); 115016d9e3a6SLisandro Dalcin 11519566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag)); 1152792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse); 115316d9e3a6SLisandro Dalcin 1154dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,PETSC_STATIC_ARRAY_LENGTH(symtlist),symtlist[0],&indx,&flag)); 115516d9e3a6SLisandro Dalcin if (flag) { 115616d9e3a6SLisandro Dalcin jac->symt = indx; 1157792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt); 115816d9e3a6SLisandro Dalcin } 115916d9e3a6SLisandro Dalcin 1160d0609cedSBarry Smith PetscOptionsHeadEnd(); 116116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 116216d9e3a6SLisandro Dalcin } 116316d9e3a6SLisandro Dalcin 116416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer) 116516d9e3a6SLisandro Dalcin { 116616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1167ace3abfcSBarry Smith PetscBool iascii; 1168feb237baSPierre Jolivet const char *symt = 0; 116916d9e3a6SLisandro Dalcin 117016d9e3a6SLisandro Dalcin PetscFunctionBegin; 11719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 117216d9e3a6SLisandro Dalcin if (iascii) { 11739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE ParaSails preconditioning\n")); 117463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," nlevels %" PetscInt_FMT "\n",jac->nlevels)); 11759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," threshold %g\n",(double)jac->threshold)); 11769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," filter %g\n",(double)jac->filter)); 11779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," load balance %g\n",(double)jac->loadbal)); 11789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," reuse nonzero structure %s\n",PetscBools[jac->ruse])); 11799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," print info to screen %s\n",PetscBools[jac->logging])); 11802fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 11812fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 11822fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 118363a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT,jac->symt); 11849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," %s\n",symt)); 118516d9e3a6SLisandro Dalcin } 118616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 118716d9e3a6SLisandro Dalcin } 11884cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/ 11894416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc) 11904cb006feSStefano Zampini { 11914cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 11924cb006feSStefano Zampini PetscInt n; 11934cb006feSStefano Zampini PetscBool flag,flag2,flag3,flag4; 11944cb006feSStefano Zampini 11954cb006feSStefano Zampini PetscFunctionBegin; 1196d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE AMS Options"); 11979566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag)); 1198792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print); 11999566063dSJacob 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)); 1200792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter); 12019566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type","Cycle type for AMS multigrid","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag)); 1202792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type); 12039566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag)); 1204792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol); 12059566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag)); 12069566063dSJacob 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)); 12079566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3)); 12089566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4)); 12094cb006feSStefano Zampini if (flag || flag2 || flag3 || flag4) { 1210792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type, 1211863406b8SStefano Zampini jac->as_relax_times, 1212863406b8SStefano Zampini jac->as_relax_weight, 1213a74df02fSJacob Faibussowitsch jac->as_omega); 12144cb006feSStefano Zampini } 12159566063dSJacob 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)); 12164cb006feSStefano Zampini n = 5; 12179566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2)); 12184cb006feSStefano Zampini if (flag || flag2) { 1219792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1220863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1221863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 1222863406b8SStefano Zampini jac->as_amg_alpha_theta, 1223863406b8SStefano Zampini jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1224a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 12254cb006feSStefano Zampini } 12269566063dSJacob 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)); 12274cb006feSStefano Zampini n = 5; 12289566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->as_amg_beta_opts,&n,&flag2)); 12294cb006feSStefano Zampini if (flag || flag2) { 1230792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1231863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1232863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 1233863406b8SStefano Zampini jac->as_amg_beta_theta, 1234863406b8SStefano Zampini jac->as_amg_beta_opts[3], /* AMG interp_type */ 1235a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 12364cb006feSStefano Zampini } 12379566063dSJacob 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)); 123823df4f25SStefano Zampini if (flag) { /* override HYPRE's default only if the options is used */ 1239792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetProjectionFrequency,jac->hsolver,jac->ams_proj_freq); 124023df4f25SStefano Zampini } 1241d0609cedSBarry Smith PetscOptionsHeadEnd(); 12424cb006feSStefano Zampini PetscFunctionReturn(0); 12434cb006feSStefano Zampini } 12444cb006feSStefano Zampini 12454cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer) 12464cb006feSStefano Zampini { 12474cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 12484cb006feSStefano Zampini PetscBool iascii; 12494cb006feSStefano Zampini 12504cb006feSStefano Zampini PetscFunctionBegin; 12519566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 12524cb006feSStefano Zampini if (iascii) { 12539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE AMS preconditioning\n")); 125463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace iterations per application %" PetscInt_FMT "\n",jac->as_max_iter)); 125563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace cycle type %" PetscInt_FMT "\n",jac->ams_cycle_type)); 125663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace iteration tolerance %g\n",(double)jac->as_tol)); 125763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother type %" PetscInt_FMT "\n",jac->as_relax_type)); 125863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," number of smoothing steps %" PetscInt_FMT "\n",jac->as_relax_times)); 125963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother weight %g\n",(double)jac->as_relax_weight)); 126063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother omega %g\n",(double)jac->as_omega)); 12614cb006feSStefano Zampini if (jac->alpha_Poisson) { 12629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," vector Poisson solver (passed in by user)\n")); 12634cb006feSStefano Zampini } else { 12649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," vector Poisson solver (computed) \n")); 12654cb006feSStefano Zampini } 126663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG coarsening type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[0])); 126763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[1])); 126863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG relaxation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[2])); 126963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG interpolation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[3])); 127063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[4])); 127163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG strength threshold %g\n",(double)jac->as_amg_alpha_theta)); 12724cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 12734cb006feSStefano Zampini if (jac->beta_Poisson) { 12749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," scalar Poisson solver (passed in by user)\n")); 12754cb006feSStefano Zampini } else { 12769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," scalar Poisson solver (computed) \n")); 12774cb006feSStefano Zampini } 127863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG coarsening type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[0])); 127963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_beta_opts[1])); 128063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG relaxation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[2])); 128163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG interpolation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[3])); 128263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_beta_opts[4])); 128363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," boomerAMG strength threshold %g\n",(double)jac->as_amg_beta_theta)); 128423df4f25SStefano Zampini if (jac->ams_beta_is_zero_part) { 128563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," compatible subspace projection frequency %" PetscInt_FMT " (-1 HYPRE uses default)\n",jac->ams_proj_freq)); 128623df4f25SStefano Zampini } 128723df4f25SStefano Zampini } else { 12889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," scalar Poisson solver not used (zero-conductivity everywhere) \n")); 12894cb006feSStefano Zampini } 12904cb006feSStefano Zampini } 12914cb006feSStefano Zampini PetscFunctionReturn(0); 12924cb006feSStefano Zampini } 12934cb006feSStefano Zampini 12944416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc) 1295863406b8SStefano Zampini { 1296863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1297863406b8SStefano Zampini PetscInt n; 1298863406b8SStefano Zampini PetscBool flag,flag2,flag3,flag4; 1299863406b8SStefano Zampini 1300863406b8SStefano Zampini PetscFunctionBegin; 1301d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE ADS Options"); 13029566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag)); 1303792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print); 13049566063dSJacob 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)); 1305792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter); 13069566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type","Cycle type for ADS multigrid","None",jac->ads_cycle_type,&jac->ads_cycle_type,&flag)); 1307792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetCycleType,jac->hsolver,jac->ads_cycle_type); 13089566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag)); 1309792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol); 13109566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type","Relaxation type for ADS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag)); 13119566063dSJacob 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)); 13129566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight","Relaxation weight for ADS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3)); 13139566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4)); 1314863406b8SStefano Zampini if (flag || flag2 || flag3 || flag4) { 1315792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type, 1316863406b8SStefano Zampini jac->as_relax_times, 1317863406b8SStefano Zampini jac->as_relax_weight, 1318a74df02fSJacob Faibussowitsch jac->as_omega); 1319863406b8SStefano Zampini } 13209566063dSJacob 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)); 1321863406b8SStefano Zampini n = 5; 13229566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options","AMG options for AMS solver inside ADS","None",jac->as_amg_alpha_opts,&n,&flag2)); 13239566063dSJacob 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)); 1324863406b8SStefano Zampini if (flag || flag2 || flag3) { 1325792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type, /* AMS cycle type */ 1326863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1327863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1328863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 1329863406b8SStefano Zampini jac->as_amg_alpha_theta, 1330863406b8SStefano Zampini jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1331a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 1332863406b8SStefano Zampini } 13339566063dSJacob 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)); 1334863406b8SStefano Zampini n = 5; 13359566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options","AMG options for vector AMG solver inside ADS","None",jac->as_amg_beta_opts,&n,&flag2)); 1336863406b8SStefano Zampini if (flag || flag2) { 1337792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1338863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1339863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 1340863406b8SStefano Zampini jac->as_amg_beta_theta, 1341863406b8SStefano Zampini jac->as_amg_beta_opts[3], /* AMG interp_type */ 1342a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 1343863406b8SStefano Zampini } 1344d0609cedSBarry Smith PetscOptionsHeadEnd(); 1345863406b8SStefano Zampini PetscFunctionReturn(0); 1346863406b8SStefano Zampini } 1347863406b8SStefano Zampini 1348863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer) 1349863406b8SStefano Zampini { 1350863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1351863406b8SStefano Zampini PetscBool iascii; 1352863406b8SStefano Zampini 1353863406b8SStefano Zampini PetscFunctionBegin; 13549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 1355863406b8SStefano Zampini if (iascii) { 13569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE ADS preconditioning\n")); 135763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace iterations per application %" PetscInt_FMT "\n",jac->as_max_iter)); 135863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace cycle type %" PetscInt_FMT "\n",jac->ads_cycle_type)); 135963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace iteration tolerance %g\n",(double)jac->as_tol)); 136063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother type %" PetscInt_FMT "\n",jac->as_relax_type)); 136163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," number of smoothing steps %" PetscInt_FMT "\n",jac->as_relax_times)); 136263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother weight %g\n",(double)jac->as_relax_weight)); 136363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," smoother omega %g\n",(double)jac->as_omega)); 13649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," AMS solver using boomerAMG\n")); 136563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," subspace cycle type %" PetscInt_FMT "\n",jac->ams_cycle_type)); 136663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," coarsening type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[0])); 136763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[1])); 136863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," relaxation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[2])); 136963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," interpolation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[3])); 137063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[4])); 137163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," strength threshold %g\n",(double)jac->as_amg_alpha_theta)); 13729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," vector Poisson solver using boomerAMG\n")); 137363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," coarsening type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[0])); 137463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_beta_opts[1])); 137563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," relaxation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[2])); 137663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," interpolation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[3])); 137763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_beta_opts[4])); 137863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," strength threshold %g\n",(double)jac->as_amg_beta_theta)); 1379863406b8SStefano Zampini } 1380863406b8SStefano Zampini PetscFunctionReturn(0); 1381863406b8SStefano Zampini } 1382863406b8SStefano Zampini 1383863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G) 13844cb006feSStefano Zampini { 13854cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 13865ac14e1cSStefano Zampini PetscBool ishypre; 13874cb006feSStefano Zampini 13884cb006feSStefano Zampini PetscFunctionBegin; 13899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre)); 13905ac14e1cSStefano Zampini if (ishypre) { 13919566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)G)); 13929566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 13935ac14e1cSStefano Zampini jac->G = G; 13945ac14e1cSStefano Zampini } else { 13959566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 13969566063dSJacob Faibussowitsch PetscCall(MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G)); 13975ac14e1cSStefano Zampini } 13984cb006feSStefano Zampini PetscFunctionReturn(0); 13994cb006feSStefano Zampini } 14004cb006feSStefano Zampini 14014cb006feSStefano Zampini /*@ 14024cb006feSStefano Zampini PCHYPRESetDiscreteGradient - Set discrete gradient matrix 14034cb006feSStefano Zampini 14044cb006feSStefano Zampini Collective on PC 14054cb006feSStefano Zampini 14064cb006feSStefano Zampini Input Parameters: 14074cb006feSStefano Zampini + pc - the preconditioning context 14084cb006feSStefano Zampini - G - the discrete gradient 14094cb006feSStefano Zampini 14104cb006feSStefano Zampini Level: intermediate 14114cb006feSStefano Zampini 141295452b02SPatrick Sanan Notes: 141395452b02SPatrick Sanan G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 1414147403d9SBarry Smith 1415863406b8SStefano 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 14164cb006feSStefano Zampini 1417db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteCurl()` 14184cb006feSStefano Zampini @*/ 14194cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 14204cb006feSStefano Zampini { 14214cb006feSStefano Zampini PetscFunctionBegin; 14224cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 14234cb006feSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 14244cb006feSStefano Zampini PetscCheckSameComm(pc,1,G,2); 1425cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G)); 14264cb006feSStefano Zampini PetscFunctionReturn(0); 14274cb006feSStefano Zampini } 14284cb006feSStefano Zampini 1429863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C) 1430863406b8SStefano Zampini { 1431863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 14325ac14e1cSStefano Zampini PetscBool ishypre; 1433863406b8SStefano Zampini 1434863406b8SStefano Zampini PetscFunctionBegin; 14359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre)); 14365ac14e1cSStefano Zampini if (ishypre) { 14379566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)C)); 14389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 14395ac14e1cSStefano Zampini jac->C = C; 14405ac14e1cSStefano Zampini } else { 14419566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 14429566063dSJacob Faibussowitsch PetscCall(MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C)); 14435ac14e1cSStefano Zampini } 1444863406b8SStefano Zampini PetscFunctionReturn(0); 1445863406b8SStefano Zampini } 1446863406b8SStefano Zampini 1447863406b8SStefano Zampini /*@ 1448863406b8SStefano Zampini PCHYPRESetDiscreteCurl - Set discrete curl matrix 1449863406b8SStefano Zampini 1450863406b8SStefano Zampini Collective on PC 1451863406b8SStefano Zampini 1452863406b8SStefano Zampini Input Parameters: 1453863406b8SStefano Zampini + pc - the preconditioning context 1454863406b8SStefano Zampini - C - the discrete curl 1455863406b8SStefano Zampini 1456863406b8SStefano Zampini Level: intermediate 1457863406b8SStefano Zampini 145895452b02SPatrick Sanan Notes: 145995452b02SPatrick Sanan C should have as many rows as the number of faces and as many columns as the number of edges in the mesh 1460147403d9SBarry Smith 1461863406b8SStefano 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 1462863406b8SStefano Zampini 1463db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()` 1464863406b8SStefano Zampini @*/ 1465863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C) 1466863406b8SStefano Zampini { 1467863406b8SStefano Zampini PetscFunctionBegin; 1468863406b8SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1469863406b8SStefano Zampini PetscValidHeaderSpecific(C,MAT_CLASSID,2); 1470863406b8SStefano Zampini PetscCheckSameComm(pc,1,C,2); 1471cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C)); 1472863406b8SStefano Zampini PetscFunctionReturn(0); 1473863406b8SStefano Zampini } 1474863406b8SStefano Zampini 14756bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 14766bf688a0SCe Qin { 14776bf688a0SCe Qin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 14786bf688a0SCe Qin PetscBool ishypre; 14796bf688a0SCe Qin PetscInt i; 14806bf688a0SCe Qin PetscFunctionBegin; 14816bf688a0SCe Qin 14829566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 14839566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 14846bf688a0SCe Qin for (i=0;i<3;++i) { 14859566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[i])); 14869566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[i])); 14876bf688a0SCe Qin } 14886bf688a0SCe Qin 14896bf688a0SCe Qin jac->dim = dim; 14906bf688a0SCe Qin if (RT_PiFull) { 14919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre)); 14926bf688a0SCe Qin if (ishypre) { 14939566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_PiFull)); 14946bf688a0SCe Qin jac->RT_PiFull = RT_PiFull; 14956bf688a0SCe Qin } else { 14969566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull)); 14976bf688a0SCe Qin } 14986bf688a0SCe Qin } 14996bf688a0SCe Qin if (RT_Pi) { 15006bf688a0SCe Qin for (i=0;i<dim;++i) { 15016bf688a0SCe Qin if (RT_Pi[i]) { 15029566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre)); 15036bf688a0SCe Qin if (ishypre) { 15049566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_Pi[i])); 15056bf688a0SCe Qin jac->RT_Pi[i] = RT_Pi[i]; 15066bf688a0SCe Qin } else { 15079566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i])); 15086bf688a0SCe Qin } 15096bf688a0SCe Qin } 15106bf688a0SCe Qin } 15116bf688a0SCe Qin } 15126bf688a0SCe Qin if (ND_PiFull) { 15139566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre)); 15146bf688a0SCe Qin if (ishypre) { 15159566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_PiFull)); 15166bf688a0SCe Qin jac->ND_PiFull = ND_PiFull; 15176bf688a0SCe Qin } else { 15189566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull)); 15196bf688a0SCe Qin } 15206bf688a0SCe Qin } 15216bf688a0SCe Qin if (ND_Pi) { 15226bf688a0SCe Qin for (i=0;i<dim;++i) { 15236bf688a0SCe Qin if (ND_Pi[i]) { 15249566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre)); 15256bf688a0SCe Qin if (ishypre) { 15269566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_Pi[i])); 15276bf688a0SCe Qin jac->ND_Pi[i] = ND_Pi[i]; 15286bf688a0SCe Qin } else { 15299566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i])); 15306bf688a0SCe Qin } 15316bf688a0SCe Qin } 15326bf688a0SCe Qin } 15336bf688a0SCe Qin } 15346bf688a0SCe Qin 15356bf688a0SCe Qin PetscFunctionReturn(0); 15366bf688a0SCe Qin } 15376bf688a0SCe Qin 15386bf688a0SCe Qin /*@ 15396bf688a0SCe Qin PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner 15406bf688a0SCe Qin 15416bf688a0SCe Qin Collective on PC 15426bf688a0SCe Qin 15436bf688a0SCe Qin Input Parameters: 15446bf688a0SCe Qin + pc - the preconditioning context 15456bf688a0SCe Qin - dim - the dimension of the problem, only used in AMS 15466bf688a0SCe Qin - RT_PiFull - Raviart-Thomas interpolation matrix 15476bf688a0SCe Qin - RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix 15486bf688a0SCe Qin - ND_PiFull - Nedelec interpolation matrix 15496bf688a0SCe Qin - ND_Pi - x/y/z component of Nedelec interpolation matrix 15506bf688a0SCe Qin 155195452b02SPatrick Sanan Notes: 155295452b02SPatrick Sanan For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL. 1553147403d9SBarry Smith 15546bf688a0SCe Qin For ADS, both type of interpolation matrices are needed. 1555147403d9SBarry Smith 15566bf688a0SCe Qin Level: intermediate 15576bf688a0SCe Qin 15586bf688a0SCe Qin @*/ 15596bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 15606bf688a0SCe Qin { 15616bf688a0SCe Qin PetscInt i; 15626bf688a0SCe Qin 15636bf688a0SCe Qin PetscFunctionBegin; 15646bf688a0SCe Qin PetscValidHeaderSpecific(pc,PC_CLASSID,1); 15656bf688a0SCe Qin if (RT_PiFull) { 15666bf688a0SCe Qin PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3); 15676bf688a0SCe Qin PetscCheckSameComm(pc,1,RT_PiFull,3); 15686bf688a0SCe Qin } 15696bf688a0SCe Qin if (RT_Pi) { 15706bf688a0SCe Qin PetscValidPointer(RT_Pi,4); 15716bf688a0SCe Qin for (i=0;i<dim;++i) { 15726bf688a0SCe Qin if (RT_Pi[i]) { 15736bf688a0SCe Qin PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4); 15746bf688a0SCe Qin PetscCheckSameComm(pc,1,RT_Pi[i],4); 15756bf688a0SCe Qin } 15766bf688a0SCe Qin } 15776bf688a0SCe Qin } 15786bf688a0SCe Qin if (ND_PiFull) { 15796bf688a0SCe Qin PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5); 15806bf688a0SCe Qin PetscCheckSameComm(pc,1,ND_PiFull,5); 15816bf688a0SCe Qin } 15826bf688a0SCe Qin if (ND_Pi) { 15836bf688a0SCe Qin PetscValidPointer(ND_Pi,6); 15846bf688a0SCe Qin for (i=0;i<dim;++i) { 15856bf688a0SCe Qin if (ND_Pi[i]) { 15866bf688a0SCe Qin PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6); 15876bf688a0SCe Qin PetscCheckSameComm(pc,1,ND_Pi[i],6); 15886bf688a0SCe Qin } 15896bf688a0SCe Qin } 15906bf688a0SCe Qin } 1591cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi)); 15926bf688a0SCe Qin PetscFunctionReturn(0); 15936bf688a0SCe Qin } 15946bf688a0SCe Qin 15955ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha) 15964cb006feSStefano Zampini { 15974cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 15985ac14e1cSStefano Zampini PetscBool ishypre; 15994cb006feSStefano Zampini 16004cb006feSStefano Zampini PetscFunctionBegin; 16019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre)); 16025ac14e1cSStefano Zampini if (ishypre) { 16035ac14e1cSStefano Zampini if (isalpha) { 16049566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 16059566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 16065ac14e1cSStefano Zampini jac->alpha_Poisson = A; 16075ac14e1cSStefano Zampini } else { 16085ac14e1cSStefano Zampini if (A) { 16099566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 16105ac14e1cSStefano Zampini } else { 16115ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 16125ac14e1cSStefano Zampini } 16139566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16145ac14e1cSStefano Zampini jac->beta_Poisson = A; 16155ac14e1cSStefano Zampini } 16165ac14e1cSStefano Zampini } else { 16175ac14e1cSStefano Zampini if (isalpha) { 16189566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 16199566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson)); 16205ac14e1cSStefano Zampini } else { 16215ac14e1cSStefano Zampini if (A) { 16229566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16239566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson)); 16245ac14e1cSStefano Zampini } else { 16259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 16265ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 16275ac14e1cSStefano Zampini } 16285ac14e1cSStefano Zampini } 16295ac14e1cSStefano Zampini } 16304cb006feSStefano Zampini PetscFunctionReturn(0); 16314cb006feSStefano Zampini } 16324cb006feSStefano Zampini 16334cb006feSStefano Zampini /*@ 16344cb006feSStefano Zampini PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix 16354cb006feSStefano Zampini 16364cb006feSStefano Zampini Collective on PC 16374cb006feSStefano Zampini 16384cb006feSStefano Zampini Input Parameters: 16394cb006feSStefano Zampini + pc - the preconditioning context 16404cb006feSStefano Zampini - A - the matrix 16414cb006feSStefano Zampini 16424cb006feSStefano Zampini Level: intermediate 16434cb006feSStefano Zampini 164495452b02SPatrick Sanan Notes: 164595452b02SPatrick Sanan A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 16464cb006feSStefano Zampini 1647db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()` 16484cb006feSStefano Zampini @*/ 16494cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 16504cb006feSStefano Zampini { 16514cb006feSStefano Zampini PetscFunctionBegin; 16524cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 16534cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 16544cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 1655cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE)); 16564cb006feSStefano Zampini PetscFunctionReturn(0); 16574cb006feSStefano Zampini } 16584cb006feSStefano Zampini 16594cb006feSStefano Zampini /*@ 16604cb006feSStefano Zampini PCHYPRESetBetaPoissonMatrix - Set Poisson matrix 16614cb006feSStefano Zampini 16624cb006feSStefano Zampini Collective on PC 16634cb006feSStefano Zampini 16644cb006feSStefano Zampini Input Parameters: 16654cb006feSStefano Zampini + pc - the preconditioning context 16664cb006feSStefano Zampini - A - the matrix 16674cb006feSStefano Zampini 16684cb006feSStefano Zampini Level: intermediate 16694cb006feSStefano Zampini 167095452b02SPatrick Sanan Notes: 167195452b02SPatrick Sanan A should be obtained by discretizing the Poisson problem with linear finite elements. 16724cb006feSStefano Zampini Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL. 16734cb006feSStefano Zampini 1674db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 16754cb006feSStefano Zampini @*/ 16764cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 16774cb006feSStefano Zampini { 16784cb006feSStefano Zampini PetscFunctionBegin; 16794cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 16804cb006feSStefano Zampini if (A) { 16814cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 16824cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 16834cb006feSStefano Zampini } 1684cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE)); 16854cb006feSStefano Zampini PetscFunctionReturn(0); 16864cb006feSStefano Zampini } 16874cb006feSStefano Zampini 16885ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo) 16894cb006feSStefano Zampini { 16904cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 16914cb006feSStefano Zampini 16924cb006feSStefano Zampini PetscFunctionBegin; 16934cb006feSStefano Zampini /* throw away any vector if already set */ 16949566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 16959566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 16969566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 16979566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(ozz->map,&jac->constants[0])); 16989566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(ozz,jac->constants[0])); 16999566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zoz->map,&jac->constants[1])); 17009566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zoz,jac->constants[1])); 17015ac14e1cSStefano Zampini jac->dim = 2; 17024cb006feSStefano Zampini if (zzo) { 17039566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zzo->map,&jac->constants[2])); 17049566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zzo,jac->constants[2])); 17055ac14e1cSStefano Zampini jac->dim++; 17064cb006feSStefano Zampini } 17074cb006feSStefano Zampini PetscFunctionReturn(0); 17084cb006feSStefano Zampini } 17094cb006feSStefano Zampini 17104cb006feSStefano Zampini /*@ 1711147403d9SBarry Smith PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis 17124cb006feSStefano Zampini 17134cb006feSStefano Zampini Collective on PC 17144cb006feSStefano Zampini 17154cb006feSStefano Zampini Input Parameters: 17164cb006feSStefano Zampini + pc - the preconditioning context 17174cb006feSStefano Zampini - ozz - vector representing (1,0,0) (or (1,0) in 2D) 17184cb006feSStefano Zampini - zoz - vector representing (0,1,0) (or (0,1) in 2D) 17194cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 17204cb006feSStefano Zampini 17214cb006feSStefano Zampini Level: intermediate 17224cb006feSStefano Zampini 17234cb006feSStefano Zampini @*/ 17244cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 17254cb006feSStefano Zampini { 17264cb006feSStefano Zampini PetscFunctionBegin; 17274cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 17284cb006feSStefano Zampini PetscValidHeaderSpecific(ozz,VEC_CLASSID,2); 17294cb006feSStefano Zampini PetscValidHeaderSpecific(zoz,VEC_CLASSID,3); 17304cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4); 17314cb006feSStefano Zampini PetscCheckSameComm(pc,1,ozz,2); 17324cb006feSStefano Zampini PetscCheckSameComm(pc,1,zoz,3); 17334cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc,1,zzo,4); 1734cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo)); 17354cb006feSStefano Zampini PetscFunctionReturn(0); 17364cb006feSStefano Zampini } 17374cb006feSStefano Zampini 1738863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 17394cb006feSStefano Zampini { 17404cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 17414cb006feSStefano Zampini Vec tv; 17424cb006feSStefano Zampini PetscInt i; 17434cb006feSStefano Zampini 17444cb006feSStefano Zampini PetscFunctionBegin; 17454cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 17469566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 17479566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 17489566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 17495ac14e1cSStefano Zampini jac->dim = dim; 17505ac14e1cSStefano Zampini 17514cb006feSStefano Zampini /* compute IJ vector for coordinates */ 17529566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)pc),&tv)); 17539566063dSJacob Faibussowitsch PetscCall(VecSetType(tv,VECSTANDARD)); 17549566063dSJacob Faibussowitsch PetscCall(VecSetSizes(tv,nloc,PETSC_DECIDE)); 17554cb006feSStefano Zampini for (i=0;i<dim;i++) { 17564cb006feSStefano Zampini PetscScalar *array; 17574cb006feSStefano Zampini PetscInt j; 17584cb006feSStefano Zampini 17599566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(tv->map,&jac->coords[i])); 17609566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(tv,&array)); 17616ea7df73SStefano Zampini for (j=0;j<nloc;j++) array[j] = coords[j*dim+i]; 17629566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(tv,&array)); 17639566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(tv,jac->coords[i])); 17644cb006feSStefano Zampini } 17659566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tv)); 17664cb006feSStefano Zampini PetscFunctionReturn(0); 17674cb006feSStefano Zampini } 17684cb006feSStefano Zampini 176916d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/ 177016d9e3a6SLisandro Dalcin 1771f7a08781SBarry Smith static PetscErrorCode PCHYPREGetType_HYPRE(PC pc,const char *name[]) 177216d9e3a6SLisandro Dalcin { 177316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 177416d9e3a6SLisandro Dalcin 177516d9e3a6SLisandro Dalcin PetscFunctionBegin; 177616d9e3a6SLisandro Dalcin *name = jac->hypre_type; 177716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 177816d9e3a6SLisandro Dalcin } 177916d9e3a6SLisandro Dalcin 1780f7a08781SBarry Smith static PetscErrorCode PCHYPRESetType_HYPRE(PC pc,const char name[]) 178116d9e3a6SLisandro Dalcin { 178216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1783ace3abfcSBarry Smith PetscBool flag; 178416d9e3a6SLisandro Dalcin 178516d9e3a6SLisandro Dalcin PetscFunctionBegin; 178616d9e3a6SLisandro Dalcin if (jac->hypre_type) { 17879566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type,name,&flag)); 17885f80ce2aSJacob Faibussowitsch PetscCheck(flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set"); 178916d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 179016d9e3a6SLisandro Dalcin } else { 17919566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &jac->hypre_type)); 179216d9e3a6SLisandro Dalcin } 179316d9e3a6SLisandro Dalcin 179416d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 179516d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 179616d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 179716d9e3a6SLisandro Dalcin 17989566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("pilut",jac->hypre_type,&flag)); 179916d9e3a6SLisandro Dalcin if (flag) { 18009566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre)); 1801792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRPilutCreate,jac->comm_hypre,&jac->hsolver); 180216d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 180316d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 180416d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 180516d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 180616d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 180716d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 180816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 180916d9e3a6SLisandro Dalcin } 18109566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("euclid",jac->hypre_type,&flag)); 1811db966c6cSHong Zhang if (flag) { 18124e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 18134e3c431bSBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid does not support 64 bit indices"); 18148bf83915SBarry Smith #endif 18159566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre)); 1816792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidCreate,jac->comm_hypre,&jac->hsolver); 1817db966c6cSHong Zhang pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 1818db966c6cSHong Zhang pc->ops->view = PCView_HYPRE_Euclid; 1819db966c6cSHong Zhang jac->destroy = HYPRE_EuclidDestroy; 1820db966c6cSHong Zhang jac->setup = HYPRE_EuclidSetup; 1821db966c6cSHong Zhang jac->solve = HYPRE_EuclidSolve; 1822db966c6cSHong Zhang jac->factorrowsize = PETSC_DEFAULT; 1823db966c6cSHong Zhang jac->eu_level = PETSC_DEFAULT; /* default */ 1824db966c6cSHong Zhang PetscFunctionReturn(0); 1825db966c6cSHong Zhang } 18269566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("parasails",jac->hypre_type,&flag)); 182716d9e3a6SLisandro Dalcin if (flag) { 18289566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre)); 1829792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsCreate,jac->comm_hypre,&jac->hsolver); 183016d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 183116d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 183216d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 183316d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 183416d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 183516d9e3a6SLisandro Dalcin /* initialize */ 183616d9e3a6SLisandro Dalcin jac->nlevels = 1; 18378966356dSPierre Jolivet jac->threshold = .1; 183816d9e3a6SLisandro Dalcin jac->filter = .1; 183916d9e3a6SLisandro Dalcin jac->loadbal = 0; 18402fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE; 18412fa5cd67SKarl Rupp else jac->logging = (int) PETSC_FALSE; 18422fa5cd67SKarl Rupp 184316d9e3a6SLisandro Dalcin jac->ruse = (int) PETSC_FALSE; 184416d9e3a6SLisandro Dalcin jac->symt = 0; 1845792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels); 1846792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter); 1847792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal); 1848792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging); 1849792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse); 1850792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt); 185116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 185216d9e3a6SLisandro Dalcin } 18539566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("boomeramg",jac->hypre_type,&flag)); 185416d9e3a6SLisandro Dalcin if (flag) { 1855792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGCreate,&jac->hsolver); 185616d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 185716d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 185816d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 185916d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 18609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG)); 18619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG)); 186216d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 186316d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 186416d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 186516d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 186616d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 186716d9e3a6SLisandro Dalcin jac->cycletype = 1; 186816d9e3a6SLisandro Dalcin jac->maxlevels = 25; 186916d9e3a6SLisandro Dalcin jac->maxiter = 1; 18708f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 187116d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 187216d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 187316d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 187416d9e3a6SLisandro Dalcin jac->coarsentype = 6; 187516d9e3a6SLisandro Dalcin jac->measuretype = 0; 18760f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 18776a251517SEike Mueller jac->smoothtype = -1; /* Not set by default */ 1878b9eb5777SEike Mueller jac->smoothnumlevels = 25; 18791810e44eSEike Mueller jac->eu_level = 0; 18801810e44eSEike Mueller jac->eu_droptolerance = 0; 18811810e44eSEike Mueller jac->eu_bj = 0; 1882589dcaf0SStefano Zampini jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */ 18830f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 188416d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 188516d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 188616d9e3a6SLisandro Dalcin jac->relaxorder = 1; 18870f1074feSSatish Balay jac->interptype = 0; 1888589dcaf0SStefano Zampini jac->Rtype = 0; 1889589dcaf0SStefano Zampini jac->Rstrongthreshold = 0.25; 1890589dcaf0SStefano Zampini jac->Rfilterthreshold = 0.0; 1891589dcaf0SStefano Zampini jac->Adroptype = -1; 1892589dcaf0SStefano Zampini jac->Adroptol = 0.0; 18930f1074feSSatish Balay jac->agg_nl = 0; 18946ea7df73SStefano Zampini jac->agg_interptype = 4; 18950f1074feSSatish Balay jac->pmax = 0; 18960f1074feSSatish Balay jac->truncfactor = 0.0; 18970f1074feSSatish Balay jac->agg_num_paths = 1; 1898589dcaf0SStefano Zampini jac->maxc = 9; 1899589dcaf0SStefano Zampini jac->minc = 1; 190022e51d31SStefano Zampini jac->nodal_coarsening = 0; 190122e51d31SStefano Zampini jac->nodal_coarsening_diag = 0; 190222e51d31SStefano Zampini jac->vec_interp_variant = 0; 190322e51d31SStefano Zampini jac->vec_interp_qmax = 0; 190422e51d31SStefano Zampini jac->vec_interp_smooth = PETSC_FALSE; 190522e51d31SStefano Zampini jac->interp_refine = 0; 19068f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 19078f87f92bSBarry Smith jac->nodal_relax_levels = 1; 19086ea7df73SStefano Zampini jac->rap2 = 0; 19096ea7df73SStefano Zampini 19106ea7df73SStefano Zampini /* GPU defaults 19116ea7df73SStefano Zampini from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options 19126ea7df73SStefano Zampini and /src/parcsr_ls/par_amg.c */ 19136ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 19146ea7df73SStefano Zampini jac->keeptranspose = PETSC_TRUE; 19156ea7df73SStefano Zampini jac->mod_rap2 = 1; 19166ea7df73SStefano Zampini jac->coarsentype = 8; 19176ea7df73SStefano Zampini jac->relaxorder = 0; 19186ea7df73SStefano Zampini jac->interptype = 6; 19196ea7df73SStefano Zampini jac->relaxtype[0] = 18; 19206ea7df73SStefano Zampini jac->relaxtype[1] = 18; 19216ea7df73SStefano Zampini jac->agg_interptype = 7; 19226ea7df73SStefano Zampini #else 19236ea7df73SStefano Zampini jac->keeptranspose = PETSC_FALSE; 19246ea7df73SStefano Zampini jac->mod_rap2 = 0; 19256ea7df73SStefano Zampini #endif 1926792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype); 1927792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels); 1928792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter); 1929792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol); 1930792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor); 1931792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold); 1932792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum); 1933792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype); 1934792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype); 1935792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder); 1936792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype); 1937792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl); 1938792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetAggInterpType,jac->hsolver,jac->agg_interptype); 1939792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax); 1940792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths); 1941792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, jac->relaxtype[0]); /* defaults coarse to 9 */ 1942792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */ 1943792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc); 1944792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc); 19456ea7df73SStefano Zampini /* GPU */ 19466ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0) 1947792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0); 1948792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRAP2,jac->hsolver, jac->rap2); 1949792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetModuleRAP2,jac->hsolver, jac->mod_rap2); 19506ea7df73SStefano Zampini #endif 19516ea7df73SStefano Zampini 1952589dcaf0SStefano Zampini /* AIR */ 19536ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0) 1954792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype); 1955792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold); 1956792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold); 1957792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol); 1958792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype); 19596ea7df73SStefano Zampini #endif 196016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 196116d9e3a6SLisandro Dalcin } 19629566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ams",jac->hypre_type,&flag)); 19634cb006feSStefano Zampini if (flag) { 19649566063dSJacob Faibussowitsch PetscCall(HYPRE_AMSCreate(&jac->hsolver)); 19654cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 19664cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 19674cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 19684cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 19694cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 19704cb006feSStefano Zampini jac->coords[0] = NULL; 19714cb006feSStefano Zampini jac->coords[1] = NULL; 19724cb006feSStefano Zampini jac->coords[2] = NULL; 19734cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 1974863406b8SStefano Zampini jac->as_print = 0; 1975863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 1976863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 19774cb006feSStefano Zampini jac->ams_cycle_type = 13; 19784cb006feSStefano Zampini /* Smoothing options */ 1979863406b8SStefano Zampini jac->as_relax_type = 2; 1980863406b8SStefano Zampini jac->as_relax_times = 1; 1981863406b8SStefano Zampini jac->as_relax_weight = 1.0; 1982863406b8SStefano Zampini jac->as_omega = 1.0; 19834cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 1984863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 1985863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 19860bdd8552SBarry Smith jac->as_amg_alpha_opts[2] = 6; 1987863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 1988863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 1989863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 19904cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 1991863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 1992863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 19930bdd8552SBarry Smith jac->as_amg_beta_opts[2] = 6; 1994863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 1995863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 1996863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 1997792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print); 1998792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter); 1999792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type); 2000792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol); 2001792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type, 2002863406b8SStefano Zampini jac->as_relax_times, 2003863406b8SStefano Zampini jac->as_relax_weight, 2004a74df02fSJacob Faibussowitsch jac->as_omega); 2005792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2006863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2007863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 2008863406b8SStefano Zampini jac->as_amg_alpha_theta, 2009863406b8SStefano Zampini jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2010a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2011792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2012863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2013863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 2014863406b8SStefano Zampini jac->as_amg_beta_theta, 2015863406b8SStefano Zampini jac->as_amg_beta_opts[3], /* AMG interp_type */ 2016a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 201723df4f25SStefano Zampini /* Zero conductivity */ 201823df4f25SStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 201923df4f25SStefano Zampini jac->ams_beta_is_zero_part = PETSC_FALSE; 20204cb006feSStefano Zampini PetscFunctionReturn(0); 20214cb006feSStefano Zampini } 20229566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ads",jac->hypre_type,&flag)); 2023863406b8SStefano Zampini if (flag) { 20249566063dSJacob Faibussowitsch PetscCall(HYPRE_ADSCreate(&jac->hsolver)); 2025863406b8SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ADS; 2026863406b8SStefano Zampini pc->ops->view = PCView_HYPRE_ADS; 2027863406b8SStefano Zampini jac->destroy = HYPRE_ADSDestroy; 2028863406b8SStefano Zampini jac->setup = HYPRE_ADSSetup; 2029863406b8SStefano Zampini jac->solve = HYPRE_ADSSolve; 2030863406b8SStefano Zampini jac->coords[0] = NULL; 2031863406b8SStefano Zampini jac->coords[1] = NULL; 2032863406b8SStefano Zampini jac->coords[2] = NULL; 2033863406b8SStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */ 2034863406b8SStefano Zampini jac->as_print = 0; 2035863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2036863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 2037863406b8SStefano Zampini jac->ads_cycle_type = 13; 2038863406b8SStefano Zampini /* Smoothing options */ 2039863406b8SStefano Zampini jac->as_relax_type = 2; 2040863406b8SStefano Zampini jac->as_relax_times = 1; 2041863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2042863406b8SStefano Zampini jac->as_omega = 1.0; 2043863406b8SStefano Zampini /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2044863406b8SStefano Zampini jac->ams_cycle_type = 14; 2045863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2046863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 2047863406b8SStefano Zampini jac->as_amg_alpha_opts[2] = 6; 2048863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2049863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2050863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 2051863406b8SStefano Zampini /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2052863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2053863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 2054863406b8SStefano Zampini jac->as_amg_beta_opts[2] = 6; 2055863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2056863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2057863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2058792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print); 2059792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter); 2060792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCycleType,jac->hsolver,jac->ams_cycle_type); 2061792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol); 2062792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type, 2063863406b8SStefano Zampini jac->as_relax_times, 2064863406b8SStefano Zampini jac->as_relax_weight, 2065a74df02fSJacob Faibussowitsch jac->as_omega); 2066792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type, /* AMG coarsen type */ 2067863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2068863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2069863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 2070863406b8SStefano Zampini jac->as_amg_alpha_theta, 2071863406b8SStefano Zampini jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2072a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2073792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2074863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2075863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 2076863406b8SStefano Zampini jac->as_amg_beta_theta, 2077863406b8SStefano Zampini jac->as_amg_beta_opts[3], /* AMG interp_type */ 2078a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 2079863406b8SStefano Zampini PetscFunctionReturn(0); 2080863406b8SStefano Zampini } 20819566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 20822fa5cd67SKarl Rupp 20830298fd71SBarry Smith jac->hypre_type = NULL; 208498921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name); 208516d9e3a6SLisandro Dalcin } 208616d9e3a6SLisandro Dalcin 208716d9e3a6SLisandro Dalcin /* 208816d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 208916d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 209016d9e3a6SLisandro Dalcin */ 2091360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc) 209216d9e3a6SLisandro Dalcin { 20934ddd07fcSJed Brown PetscInt indx; 2094db966c6cSHong Zhang const char *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"}; 2095ace3abfcSBarry Smith PetscBool flg; 209616d9e3a6SLisandro Dalcin 209716d9e3a6SLisandro Dalcin PetscFunctionBegin; 2098d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE preconditioner options"); 2099dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,PETSC_STATIC_ARRAY_LENGTH(type),"boomeramg",&indx,&flg)); 210016d9e3a6SLisandro Dalcin if (flg) { 21019566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc,type[indx])); 210202a17cd4SBarry Smith } else { 21039566063dSJacob Faibussowitsch PetscCall(PCHYPRESetType_HYPRE(pc,"boomeramg")); 210416d9e3a6SLisandro Dalcin } 21051baa6e33SBarry Smith if (pc->ops->setfromoptions) PetscCall(pc->ops->setfromoptions(PetscOptionsObject,pc)); 2106d0609cedSBarry Smith PetscOptionsHeadEnd(); 210716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 210816d9e3a6SLisandro Dalcin } 210916d9e3a6SLisandro Dalcin 211016d9e3a6SLisandro Dalcin /*@C 211116d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 211216d9e3a6SLisandro Dalcin 211316d9e3a6SLisandro Dalcin Input Parameters: 211416d9e3a6SLisandro Dalcin + pc - the preconditioner context 2115db966c6cSHong Zhang - name - either euclid, pilut, parasails, boomeramg, ams, ads 211616d9e3a6SLisandro Dalcin 211716d9e3a6SLisandro Dalcin Options Database Keys: 2118db966c6cSHong Zhang -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 211916d9e3a6SLisandro Dalcin 212016d9e3a6SLisandro Dalcin Level: intermediate 212116d9e3a6SLisandro Dalcin 2122db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, 2123db781477SPatrick Sanan `PCHYPRE` 212416d9e3a6SLisandro Dalcin 212516d9e3a6SLisandro Dalcin @*/ 21267087cfbeSBarry Smith PetscErrorCode PCHYPRESetType(PC pc,const char name[]) 212716d9e3a6SLisandro Dalcin { 212816d9e3a6SLisandro Dalcin PetscFunctionBegin; 21290700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 213016d9e3a6SLisandro Dalcin PetscValidCharPointer(name,2); 2131cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name)); 213216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 213316d9e3a6SLisandro Dalcin } 213416d9e3a6SLisandro Dalcin 213516d9e3a6SLisandro Dalcin /*@C 213616d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 213716d9e3a6SLisandro Dalcin 213816d9e3a6SLisandro Dalcin Input Parameter: 213916d9e3a6SLisandro Dalcin . pc - the preconditioner context 214016d9e3a6SLisandro Dalcin 214116d9e3a6SLisandro Dalcin Output Parameter: 2142db966c6cSHong Zhang . name - either euclid, pilut, parasails, boomeramg, ams, ads 214316d9e3a6SLisandro Dalcin 214416d9e3a6SLisandro Dalcin Level: intermediate 214516d9e3a6SLisandro Dalcin 2146db781477SPatrick Sanan .seealso: `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`, 2147db781477SPatrick Sanan `PCHYPRE` 214816d9e3a6SLisandro Dalcin 214916d9e3a6SLisandro Dalcin @*/ 21507087cfbeSBarry Smith PetscErrorCode PCHYPREGetType(PC pc,const char *name[]) 215116d9e3a6SLisandro Dalcin { 215216d9e3a6SLisandro Dalcin PetscFunctionBegin; 21530700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 215416d9e3a6SLisandro Dalcin PetscValidPointer(name,2); 2155cac4c232SBarry Smith PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name)); 215616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 215716d9e3a6SLisandro Dalcin } 215816d9e3a6SLisandro Dalcin 2159db6f9c32SMark Adams /*@C 2160db6f9c32SMark Adams PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use 2161db6f9c32SMark Adams 2162db6f9c32SMark Adams Logically Collective on PC 2163db6f9c32SMark Adams 2164db6f9c32SMark Adams Input Parameters: 2165db6f9c32SMark Adams + pc - the hypre context 2166db6f9c32SMark Adams - type - one of 'cusparse', 'hypre' 2167db6f9c32SMark Adams 2168db6f9c32SMark Adams Options Database Key: 216967b8a455SSatish Balay . -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre 2170db6f9c32SMark Adams 2171db6f9c32SMark Adams Level: intermediate 2172db6f9c32SMark Adams 2173db781477SPatrick Sanan .seealso: `PCMGGalerkinGetMatProductAlgorithm()` 2174db6f9c32SMark Adams 2175db6f9c32SMark Adams @*/ 2176db6f9c32SMark Adams PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc,const char name[]) 2177db6f9c32SMark Adams { 2178db6f9c32SMark Adams PetscFunctionBegin; 2179db6f9c32SMark Adams PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2180cac4c232SBarry Smith PetscTryMethod(pc,"PCMGGalerkinSetMatProductAlgorithm_C",(PC,const char[]),(pc,name)); 2181db6f9c32SMark Adams PetscFunctionReturn(0); 2182db6f9c32SMark Adams } 2183db6f9c32SMark Adams 2184db6f9c32SMark Adams /*@C 2185db6f9c32SMark Adams PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre 2186db6f9c32SMark Adams 2187db6f9c32SMark Adams Not Collective 2188db6f9c32SMark Adams 2189db6f9c32SMark Adams Input Parameter: 2190db6f9c32SMark Adams . pc - the multigrid context 2191db6f9c32SMark Adams 2192db6f9c32SMark Adams Output Parameter: 2193db6f9c32SMark Adams . name - one of 'cusparse', 'hypre' 2194db6f9c32SMark Adams 2195db6f9c32SMark Adams Level: intermediate 2196db6f9c32SMark Adams 2197db781477SPatrick Sanan .seealso: `PCMGGalerkinSetMatProductAlgorithm()` 2198db6f9c32SMark Adams 2199db6f9c32SMark Adams @*/ 2200db6f9c32SMark Adams PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc,const char *name[]) 2201db6f9c32SMark Adams { 2202db6f9c32SMark Adams PetscFunctionBegin; 2203db6f9c32SMark Adams PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2204cac4c232SBarry Smith PetscTryMethod(pc,"PCMGGalerkinGetMatProductAlgorithm_C",(PC,const char*[]),(pc,name)); 2205db6f9c32SMark Adams PetscFunctionReturn(0); 2206db6f9c32SMark Adams } 2207db6f9c32SMark Adams 220816d9e3a6SLisandro Dalcin /*MC 220916d9e3a6SLisandro Dalcin PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre 221016d9e3a6SLisandro Dalcin 221116d9e3a6SLisandro Dalcin Options Database Keys: 2212db966c6cSHong Zhang + -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads 2213ead8c081SBarry Smith . -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal()) 2214ead8c081SBarry Smith . -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant()) 2215ead8c081SBarry Smith - Many others, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX preconditioner 221616d9e3a6SLisandro Dalcin 221716d9e3a6SLisandro Dalcin Level: intermediate 221816d9e3a6SLisandro Dalcin 221995452b02SPatrick Sanan Notes: 222095452b02SPatrick Sanan Apart from pc_hypre_type (for which there is PCHYPRESetType()), 222116d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 222216d9e3a6SLisandro Dalcin or with PetscOptionsSetValue(), there are no functions to set them) 222316d9e3a6SLisandro Dalcin 2224c231f9e3SBarryFSmith The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations 22250f1074feSSatish Balay (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if 22260f1074feSSatish Balay -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner 2227c231f9e3SBarryFSmith (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of 22288f87f92bSBarry Smith iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations 22290f1074feSSatish Balay and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10 22300f1074feSSatish Balay then AT MOST twenty V-cycles of boomeramg will be called. 223116d9e3a6SLisandro Dalcin 22320f1074feSSatish Balay Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation 22330f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 22340f1074feSSatish Balay Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi. 223516d9e3a6SLisandro Dalcin If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly 223616d9e3a6SLisandro Dalcin and use -ksp_max_it to control the number of V-cycles. 223716d9e3a6SLisandro Dalcin (see the PETSc FAQ.html at the PETSc website under the Documentation tab). 223816d9e3a6SLisandro Dalcin 223916d9e3a6SLisandro Dalcin 2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option 224016d9e3a6SLisandro Dalcin -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L. 224116d9e3a6SLisandro Dalcin 22425272c319SBarry Smith MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use 2243fdd15c9aSJunchao Zhang the following two options: 22440b1a5bd9SEric Chamberland 22459e5bc791SBarry Smith See PCPFMG for access to the hypre Struct PFMG solver 22469e5bc791SBarry Smith 2247ead8c081SBarry Smith GPU Notes: 2248ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda 2249ead8c081SBarry Smith Then pass VECCUDA vectors and MATAIJCUSPARSE matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2250ead8c081SBarry Smith 2251ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip 2252ead8c081SBarry Smith Then pass VECHIP vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2253ead8c081SBarry Smith 2254db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, 2255db781477SPatrick Sanan `PCHYPRESetType()`, `PCPFMG` 225616d9e3a6SLisandro Dalcin 225716d9e3a6SLisandro Dalcin M*/ 225816d9e3a6SLisandro Dalcin 22598cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 226016d9e3a6SLisandro Dalcin { 226116d9e3a6SLisandro Dalcin PC_HYPRE *jac; 226216d9e3a6SLisandro Dalcin 226316d9e3a6SLisandro Dalcin PetscFunctionBegin; 22649566063dSJacob Faibussowitsch PetscCall(PetscNewLog(pc,&jac)); 22652fa5cd67SKarl Rupp 226616d9e3a6SLisandro Dalcin pc->data = jac; 22678695de01SBarry Smith pc->ops->reset = PCReset_HYPRE; 226816d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 226916d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 227016d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 227116d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 227216d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 22739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE)); 22749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE)); 22759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE)); 22769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE)); 22779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE)); 22789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE)); 22799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE)); 22809566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE)); 22819566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG)); 22829566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG)); 22836ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 22846ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 22859566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 22866ea7df73SStefano Zampini #endif 22876ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 22889566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 22896ea7df73SStefano Zampini #endif 22906ea7df73SStefano Zampini #endif 229116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 229216d9e3a6SLisandro Dalcin } 2293ebc551c0SBarry Smith 2294f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/ 2295f91d8e95SBarry Smith 2296ebc551c0SBarry Smith typedef struct { 229768326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 2298f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 22999e5bc791SBarry Smith 23009e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 23014ddd07fcSJed Brown PetscInt its; 23029e5bc791SBarry Smith double tol; 23034ddd07fcSJed Brown PetscInt relax_type; 23044ddd07fcSJed Brown PetscInt rap_type; 23054ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 23064ddd07fcSJed Brown PetscInt max_levels; 2307ebc551c0SBarry Smith } PC_PFMG; 2308ebc551c0SBarry Smith 2309ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc) 2310ebc551c0SBarry Smith { 2311f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 2312ebc551c0SBarry Smith 2313ebc551c0SBarry Smith PetscFunctionBegin; 2314792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy,ex->hsolver); 23159566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 23169566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 2317ebc551c0SBarry Smith PetscFunctionReturn(0); 2318ebc551c0SBarry Smith } 2319ebc551c0SBarry Smith 23209e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"}; 23219e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"}; 23229e5bc791SBarry Smith 2323ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer) 2324ebc551c0SBarry Smith { 2325ace3abfcSBarry Smith PetscBool iascii; 2326f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 2327ebc551c0SBarry Smith 2328ebc551c0SBarry Smith PetscFunctionBegin; 23299566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 23309e5bc791SBarry Smith if (iascii) { 23319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE PFMG preconditioning\n")); 233263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max iterations %" PetscInt_FMT "\n",ex->its)); 23339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," tolerance %g\n",ex->tol)); 23349566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," relax type %s\n",PFMGRelaxType[ex->relax_type])); 23359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," RAP type %s\n",PFMGRAPType[ex->rap_type])); 233663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n",ex->num_pre_relax,ex->num_post_relax)); 233763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max levels %" PetscInt_FMT "\n",ex->max_levels)); 23389e5bc791SBarry Smith } 2339ebc551c0SBarry Smith PetscFunctionReturn(0); 2340ebc551c0SBarry Smith } 2341ebc551c0SBarry Smith 23424416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc) 2343ebc551c0SBarry Smith { 2344f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 2345ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2346ebc551c0SBarry Smith 2347ebc551c0SBarry Smith PetscFunctionBegin; 2348d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"PFMG options"); 23499566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL)); 235068326731SBarry Smith if (flg) { 2351792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetPrintLevel,ex->hsolver,3); 235268326731SBarry Smith } 23539566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL)); 2354792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter,ex->hsolver,ex->its); 23559566063dSJacob 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)); 2356792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax,ex->hsolver,ex->num_pre_relax); 23579566063dSJacob 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)); 2358792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax,ex->hsolver,ex->num_post_relax); 23599e5bc791SBarry Smith 23609566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL)); 2361792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxLevels,ex->hsolver,ex->max_levels); 23623b46a515SGlenn Hammond 23639566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL)); 2364792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol,ex->hsolver,ex->tol); 2365dd39110bSPierre 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)); 2366792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRelaxType,ex->hsolver, ex->relax_type); 2367dd39110bSPierre 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)); 2368792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRAPType,ex->hsolver, ex->rap_type); 2369d0609cedSBarry Smith PetscOptionsHeadEnd(); 2370ebc551c0SBarry Smith PetscFunctionReturn(0); 2371ebc551c0SBarry Smith } 2372ebc551c0SBarry Smith 2373f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y) 2374f91d8e95SBarry Smith { 2375f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 2376d9ca1df4SBarry Smith PetscScalar *yy; 2377d9ca1df4SBarry Smith const PetscScalar *xx; 23784ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 23792cf14000SStefano Zampini HYPRE_Int hlower[3],hupper[3]; 238068326731SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 2381f91d8e95SBarry Smith 2382f91d8e95SBarry Smith PetscFunctionBegin; 23839566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 23849566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2])); 23852cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2386f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 2387f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 2388f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 23892cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 23902cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 23912cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 23922cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 23932cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 23942cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2395f91d8e95SBarry Smith 2396f91d8e95SBarry Smith /* copy x values over to hypre */ 2397792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetConstantValues,mx->hb,0.0); 23989566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xx)); 2399792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetBoxValues,mx->hb,hlower,hupper,(HYPRE_Complex*)xx); 24009566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xx)); 2401792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorAssemble,mx->hb); 2402792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSolve,ex->hsolver,mx->hmat,mx->hb,mx->hx); 2403f91d8e95SBarry Smith 2404f91d8e95SBarry Smith /* copy solution values back to PETSc */ 24059566063dSJacob Faibussowitsch PetscCall(VecGetArray(y,&yy)); 2406792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorGetBoxValues,mx->hx,hlower,hupper,(HYPRE_Complex*)yy); 24079566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y,&yy)); 2408f91d8e95SBarry Smith PetscFunctionReturn(0); 2409f91d8e95SBarry Smith } 2410f91d8e95SBarry Smith 2411ace3abfcSBarry 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) 24129e5bc791SBarry Smith { 24139e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG*)pc->data; 24142cf14000SStefano Zampini HYPRE_Int oits; 24159e5bc791SBarry Smith 24169e5bc791SBarry Smith PetscFunctionBegin; 24179566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 2418792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter,jac->hsolver,its*jac->its); 2419792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol,jac->hsolver,rtol); 24209e5bc791SBarry Smith 24219566063dSJacob Faibussowitsch PetscCall(PCApply_PFMG(pc,b,y)); 2422792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGGetNumIterations,jac->hsolver,&oits); 24239e5bc791SBarry Smith *outits = oits; 24249e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 24259e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 2426792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol,jac->hsolver,jac->tol); 2427792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter,jac->hsolver,jac->its); 24289e5bc791SBarry Smith PetscFunctionReturn(0); 24299e5bc791SBarry Smith } 24309e5bc791SBarry Smith 24313a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc) 24323a32d3dbSGlenn Hammond { 24333a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG*) pc->data; 24343a32d3dbSGlenn Hammond Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 2435ace3abfcSBarry Smith PetscBool flg; 24363a32d3dbSGlenn Hammond 24373a32d3dbSGlenn Hammond PetscFunctionBegin; 24389566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg)); 243928b400f6SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner"); 24403a32d3dbSGlenn Hammond 24413a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 2442792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy,ex->hsolver); 2443792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver); 2444792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetup,ex->hsolver,mx->hmat,mx->hb,mx->hx); 2445792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetZeroGuess,ex->hsolver); 24463a32d3dbSGlenn Hammond PetscFunctionReturn(0); 24473a32d3dbSGlenn Hammond } 24483a32d3dbSGlenn Hammond 2449ebc551c0SBarry Smith /*MC 2450ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 2451ebc551c0SBarry Smith 2452ebc551c0SBarry Smith Level: advanced 2453ebc551c0SBarry Smith 24549e5bc791SBarry Smith Options Database: 245567b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner 245667b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve 245767b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve 245867b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG 24599e5bc791SBarry 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 24609e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 2461f91d8e95SBarry Smith 246295452b02SPatrick Sanan Notes: 246395452b02SPatrick Sanan This is for CELL-centered descretizations 24649e5bc791SBarry Smith 24658e395302SJed Brown This must be used with the MATHYPRESTRUCT matrix type. 2466aa219208SBarry Smith This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA. 24679e5bc791SBarry Smith 2468db781477SPatrick Sanan .seealso: `PCMG`, `MATHYPRESTRUCT` 2469ebc551c0SBarry Smith M*/ 2470ebc551c0SBarry Smith 24718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 2472ebc551c0SBarry Smith { 2473ebc551c0SBarry Smith PC_PFMG *ex; 2474ebc551c0SBarry Smith 2475ebc551c0SBarry Smith PetscFunctionBegin; 24769566063dSJacob Faibussowitsch PetscCall(PetscNew(&ex)); \ 247768326731SBarry Smith pc->data = ex; 2478ebc551c0SBarry Smith 24799e5bc791SBarry Smith ex->its = 1; 24809e5bc791SBarry Smith ex->tol = 1.e-8; 24819e5bc791SBarry Smith ex->relax_type = 1; 24829e5bc791SBarry Smith ex->rap_type = 0; 24839e5bc791SBarry Smith ex->num_pre_relax = 1; 24849e5bc791SBarry Smith ex->num_post_relax = 1; 24853b46a515SGlenn Hammond ex->max_levels = 0; 24869e5bc791SBarry Smith 2487ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 2488ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 2489ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 2490f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 24919e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 249268326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 24932fa5cd67SKarl Rupp 24949566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 2495792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver); 2496ebc551c0SBarry Smith PetscFunctionReturn(0); 2497ebc551c0SBarry Smith } 2498d851a50bSGlenn Hammond 2499325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/ 2500325fc9f4SBarry Smith 2501d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 2502d851a50bSGlenn Hammond typedef struct { 2503d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 2504d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 2505d851a50bSGlenn Hammond 2506d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 25074ddd07fcSJed Brown PetscInt its; 2508d851a50bSGlenn Hammond double tol; 25094ddd07fcSJed Brown PetscInt relax_type; 25104ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 2511d851a50bSGlenn Hammond } PC_SysPFMG; 2512d851a50bSGlenn Hammond 2513d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc) 2514d851a50bSGlenn Hammond { 2515d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2516d851a50bSGlenn Hammond 2517d851a50bSGlenn Hammond PetscFunctionBegin; 2518792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy,ex->ss_solver); 25199566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 25209566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 2521d851a50bSGlenn Hammond PetscFunctionReturn(0); 2522d851a50bSGlenn Hammond } 2523d851a50bSGlenn Hammond 2524d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"}; 2525d851a50bSGlenn Hammond 2526d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer) 2527d851a50bSGlenn Hammond { 2528ace3abfcSBarry Smith PetscBool iascii; 2529d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2530d851a50bSGlenn Hammond 2531d851a50bSGlenn Hammond PetscFunctionBegin; 25329566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 2533d851a50bSGlenn Hammond if (iascii) { 25349566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG preconditioning\n")); 253563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max iterations %" PetscInt_FMT "\n",ex->its)); 25369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," tolerance %g\n",ex->tol)); 25379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," relax type %s\n",PFMGRelaxType[ex->relax_type])); 253863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n",ex->num_pre_relax,ex->num_post_relax)); 2539d851a50bSGlenn Hammond } 2540d851a50bSGlenn Hammond PetscFunctionReturn(0); 2541d851a50bSGlenn Hammond } 2542d851a50bSGlenn Hammond 25434416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc) 2544d851a50bSGlenn Hammond { 2545d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2546ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2547d851a50bSGlenn Hammond 2548d851a50bSGlenn Hammond PetscFunctionBegin; 2549d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"SysPFMG options"); 25509566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL)); 2551d851a50bSGlenn Hammond if (flg) { 2552792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetPrintLevel,ex->ss_solver,3); 2553d851a50bSGlenn Hammond } 25549566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL)); 2555792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,ex->ss_solver,ex->its); 25569566063dSJacob 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)); 2557792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPreRelax,ex->ss_solver,ex->num_pre_relax); 25589566063dSJacob 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)); 2559792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPostRelax,ex->ss_solver,ex->num_post_relax); 2560d851a50bSGlenn Hammond 25619566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL)); 2562792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol,ex->ss_solver,ex->tol); 2563dd39110bSPierre 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)); 2564792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetRelaxType,ex->ss_solver, ex->relax_type); 2565d0609cedSBarry Smith PetscOptionsHeadEnd(); 2566d851a50bSGlenn Hammond PetscFunctionReturn(0); 2567d851a50bSGlenn Hammond } 2568d851a50bSGlenn Hammond 2569d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y) 2570d851a50bSGlenn Hammond { 2571d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2572d9ca1df4SBarry Smith PetscScalar *yy; 2573d9ca1df4SBarry Smith const PetscScalar *xx; 25744ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 25752cf14000SStefano Zampini HYPRE_Int hlower[3],hupper[3]; 2576d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 25774ddd07fcSJed Brown PetscInt ordering= mx->dofs_order; 25784ddd07fcSJed Brown PetscInt nvars = mx->nvars; 25794ddd07fcSJed Brown PetscInt part = 0; 25804ddd07fcSJed Brown PetscInt size; 25814ddd07fcSJed Brown PetscInt i; 2582d851a50bSGlenn Hammond 2583d851a50bSGlenn Hammond PetscFunctionBegin; 25849566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 25859566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2])); 25862cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2587d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 2588d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 2589d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 25902cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 25912cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 25922cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 25932cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 25942cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 25952cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2596d851a50bSGlenn Hammond 2597d851a50bSGlenn Hammond size = 1; 25982fa5cd67SKarl Rupp for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1); 25992fa5cd67SKarl Rupp 2600d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 2601d851a50bSGlenn Hammond if (ordering) { 2602792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0); 26039566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xx)); 2604792fecdfSBarry Smith for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))); 26059566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xx)); 2606792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble,mx->ss_b); 2607792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructMatrixMatvec,1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x); 2608792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x); 2609d851a50bSGlenn Hammond 2610d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 26119566063dSJacob Faibussowitsch PetscCall(VecGetArray(y,&yy)); 2612792fecdfSBarry Smith for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))); 26139566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y,&yy)); 2614a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 2615d851a50bSGlenn Hammond PetscScalar *z; 26164ddd07fcSJed Brown PetscInt j, k; 2617d851a50bSGlenn Hammond 26189566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvars*size,&z)); 2619792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0); 26209566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xx)); 2621d851a50bSGlenn Hammond 2622d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 2623d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 2624d851a50bSGlenn Hammond k= i*nvars; 26252fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j]; 2626d851a50bSGlenn Hammond } 2627792fecdfSBarry Smith for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))); 26289566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xx)); 2629792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble,mx->ss_b); 2630792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x); 2631d851a50bSGlenn Hammond 2632d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 26339566063dSJacob Faibussowitsch PetscCall(VecGetArray(y,&yy)); 2634792fecdfSBarry Smith for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))); 2635d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 2636d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 2637d851a50bSGlenn Hammond k= i*nvars; 26382fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i]; 2639d851a50bSGlenn Hammond } 26409566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y,&yy)); 26419566063dSJacob Faibussowitsch PetscCall(PetscFree(z)); 2642d851a50bSGlenn Hammond } 2643d851a50bSGlenn Hammond PetscFunctionReturn(0); 2644d851a50bSGlenn Hammond } 2645d851a50bSGlenn Hammond 2646ace3abfcSBarry 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) 2647d851a50bSGlenn Hammond { 2648d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG*)pc->data; 26492cf14000SStefano Zampini HYPRE_Int oits; 2650d851a50bSGlenn Hammond 2651d851a50bSGlenn Hammond PetscFunctionBegin; 26529566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation,&cite)); 2653792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,its*jac->its); 2654792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,rtol); 26559566063dSJacob Faibussowitsch PetscCall(PCApply_SysPFMG(pc,b,y)); 2656792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGGetNumIterations,jac->ss_solver,&oits); 2657d851a50bSGlenn Hammond *outits = oits; 2658d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 2659d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 2660792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,jac->tol); 2661792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,jac->its); 2662d851a50bSGlenn Hammond PetscFunctionReturn(0); 2663d851a50bSGlenn Hammond } 2664d851a50bSGlenn Hammond 2665d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc) 2666d851a50bSGlenn Hammond { 2667d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 2668d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 2669ace3abfcSBarry Smith PetscBool flg; 2670d851a50bSGlenn Hammond 2671d851a50bSGlenn Hammond PetscFunctionBegin; 26729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg)); 267328b400f6SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner"); 2674d851a50bSGlenn Hammond 2675d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 2676792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy,ex->ss_solver); 2677792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver); 2678792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetZeroGuess,ex->ss_solver); 2679792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetup,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x); 2680d851a50bSGlenn Hammond PetscFunctionReturn(0); 2681d851a50bSGlenn Hammond } 2682d851a50bSGlenn Hammond 2683d851a50bSGlenn Hammond /*MC 2684d851a50bSGlenn Hammond PCSysPFMG - the hypre SysPFMG multigrid solver 2685d851a50bSGlenn Hammond 2686d851a50bSGlenn Hammond Level: advanced 2687d851a50bSGlenn Hammond 2688d851a50bSGlenn Hammond Options Database: 268967b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner 269067b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid 269167b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid 269267b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG 269367b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles 2694d851a50bSGlenn Hammond 269595452b02SPatrick Sanan Notes: 269695452b02SPatrick Sanan This is for CELL-centered descretizations 2697d851a50bSGlenn Hammond 2698f6680f47SSatish Balay This must be used with the MATHYPRESSTRUCT matrix type. 2699aa219208SBarry Smith This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA. 2700d851a50bSGlenn Hammond Also, only cell-centered variables. 2701d851a50bSGlenn Hammond 2702db781477SPatrick Sanan .seealso: `PCMG`, `MATHYPRESSTRUCT` 2703d851a50bSGlenn Hammond M*/ 2704d851a50bSGlenn Hammond 27058cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 2706d851a50bSGlenn Hammond { 2707d851a50bSGlenn Hammond PC_SysPFMG *ex; 2708d851a50bSGlenn Hammond 2709d851a50bSGlenn Hammond PetscFunctionBegin; 27109566063dSJacob Faibussowitsch PetscCall(PetscNew(&ex)); \ 2711d851a50bSGlenn Hammond pc->data = ex; 2712d851a50bSGlenn Hammond 2713d851a50bSGlenn Hammond ex->its = 1; 2714d851a50bSGlenn Hammond ex->tol = 1.e-8; 2715d851a50bSGlenn Hammond ex->relax_type = 1; 2716d851a50bSGlenn Hammond ex->num_pre_relax = 1; 2717d851a50bSGlenn Hammond ex->num_post_relax = 1; 2718d851a50bSGlenn Hammond 2719d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 2720d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 2721d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 2722d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 2723d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 2724d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 27252fa5cd67SKarl Rupp 27269566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm)); 2727792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver); 2728d851a50bSGlenn Hammond PetscFunctionReturn(0); 2729d851a50bSGlenn Hammond } 2730