116d9e3a6SLisandro Dalcin 216d9e3a6SLisandro Dalcin /* 316d9e3a6SLisandro Dalcin Provides an interface to the LLNL package hypre 416d9e3a6SLisandro Dalcin */ 50f1074feSSatish Balay 60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */ 70f1074feSSatish Balay 8b45d2f2cSJed Brown #include <petsc-private/pcimpl.h> /*I "petscpc.h" I*/ 9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h> 104cb006feSStefano Zampini #include <_hypre_parcsr_ls.h> 1116d9e3a6SLisandro Dalcin 12dff31646SBarry Smith static PetscBool cite = PETSC_FALSE; 131f817a21SBarry 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{http://www.llnl.gov/CASC/hypre/}}\n}\n"; 141f817a21SBarry Smith 1516d9e3a6SLisandro Dalcin /* 1616d9e3a6SLisandro Dalcin Private context (data structure) for the preconditioner. 1716d9e3a6SLisandro Dalcin */ 1816d9e3a6SLisandro Dalcin typedef struct { 1916d9e3a6SLisandro Dalcin HYPRE_Solver hsolver; 2016d9e3a6SLisandro Dalcin HYPRE_IJMatrix ij; 2116d9e3a6SLisandro Dalcin HYPRE_IJVector b,x; 2216d9e3a6SLisandro Dalcin 234ddd07fcSJed Brown HYPRE_Int (*destroy)(HYPRE_Solver); 244ddd07fcSJed Brown HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 254ddd07fcSJed Brown HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 2616d9e3a6SLisandro Dalcin 2716d9e3a6SLisandro Dalcin MPI_Comm comm_hypre; 2816d9e3a6SLisandro Dalcin char *hypre_type; 2916d9e3a6SLisandro Dalcin 3016d9e3a6SLisandro Dalcin /* options for Pilut and BoomerAMG*/ 314ddd07fcSJed Brown PetscInt maxiter; 3216d9e3a6SLisandro Dalcin double tol; 3316d9e3a6SLisandro Dalcin 3416d9e3a6SLisandro Dalcin /* options for Pilut */ 354ddd07fcSJed Brown PetscInt factorrowsize; 3616d9e3a6SLisandro Dalcin 3716d9e3a6SLisandro Dalcin /* options for ParaSails */ 384ddd07fcSJed Brown PetscInt nlevels; 3916d9e3a6SLisandro Dalcin double threshhold; 4016d9e3a6SLisandro Dalcin double filter; 414ddd07fcSJed Brown PetscInt sym; 4216d9e3a6SLisandro Dalcin double loadbal; 434ddd07fcSJed Brown PetscInt logging; 444ddd07fcSJed Brown PetscInt ruse; 454ddd07fcSJed Brown PetscInt symt; 4616d9e3a6SLisandro Dalcin 4722b6d1caSBarry Smith /* options for BoomerAMG */ 48ace3abfcSBarry Smith PetscBool printstatistics; 4916d9e3a6SLisandro Dalcin 5016d9e3a6SLisandro Dalcin /* options for BoomerAMG */ 514ddd07fcSJed Brown PetscInt cycletype; 524ddd07fcSJed Brown PetscInt maxlevels; 5316d9e3a6SLisandro Dalcin double strongthreshold; 5416d9e3a6SLisandro Dalcin double maxrowsum; 554ddd07fcSJed Brown PetscInt gridsweeps[3]; 564ddd07fcSJed Brown PetscInt coarsentype; 574ddd07fcSJed Brown PetscInt measuretype; 584ddd07fcSJed Brown PetscInt relaxtype[3]; 5916d9e3a6SLisandro Dalcin double relaxweight; 6016d9e3a6SLisandro Dalcin double outerrelaxweight; 614ddd07fcSJed Brown PetscInt relaxorder; 6216d9e3a6SLisandro Dalcin double truncfactor; 63ace3abfcSBarry Smith PetscBool applyrichardson; 644ddd07fcSJed Brown PetscInt pmax; 654ddd07fcSJed Brown PetscInt interptype; 664ddd07fcSJed Brown PetscInt agg_nl; 674ddd07fcSJed Brown PetscInt agg_num_paths; 684ddd07fcSJed Brown PetscInt nodal_coarsen; 69ace3abfcSBarry Smith PetscBool nodal_relax; 704ddd07fcSJed Brown PetscInt nodal_relax_levels; 714cb006feSStefano Zampini 724cb006feSStefano Zampini /* options for AMS */ 734cb006feSStefano Zampini PetscInt ams_print; 744cb006feSStefano Zampini PetscInt ams_max_iter; 754cb006feSStefano Zampini PetscInt ams_cycle_type; 764cb006feSStefano Zampini PetscReal ams_tol; 774cb006feSStefano Zampini PetscInt ams_relax_type; 784cb006feSStefano Zampini PetscInt ams_relax_times; 794cb006feSStefano Zampini PetscReal ams_relax_weight; 804cb006feSStefano Zampini PetscReal ams_omega; 814cb006feSStefano Zampini PetscInt ams_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson */ 824cb006feSStefano Zampini PetscReal ams_amg_alpha_theta; /* AMG strength for vector Poisson */ 834cb006feSStefano Zampini PetscInt ams_amg_beta_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson */ 844cb006feSStefano Zampini PetscReal ams_amg_beta_theta; /* AMG strength for scalar Poisson */ 854cb006feSStefano Zampini 864cb006feSStefano Zampini /* additional data */ 874cb006feSStefano Zampini HYPRE_IJVector coords[3]; 884cb006feSStefano Zampini HYPRE_IJVector constants[3]; 894cb006feSStefano Zampini HYPRE_IJMatrix G; 904cb006feSStefano Zampini HYPRE_IJMatrix alpha_Poisson; 914cb006feSStefano Zampini HYPRE_IJMatrix beta_Poisson; 924cb006feSStefano Zampini PetscBool ams_beta_is_zero; 9316d9e3a6SLisandro Dalcin } PC_HYPRE; 9416d9e3a6SLisandro Dalcin 95d2128fa2SBarry Smith #undef __FUNCT__ 96d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver" 97d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver) 98d2128fa2SBarry Smith { 99d2128fa2SBarry Smith PC_HYPRE *jac = (PC_HYPRE*)pc->data; 100d2128fa2SBarry Smith 101d2128fa2SBarry Smith PetscFunctionBegin; 102d2128fa2SBarry Smith *hsolver = jac->hsolver; 103d2128fa2SBarry Smith PetscFunctionReturn(0); 104d2128fa2SBarry Smith } 10516d9e3a6SLisandro Dalcin 10616d9e3a6SLisandro Dalcin #undef __FUNCT__ 10716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE" 10816d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc) 10916d9e3a6SLisandro Dalcin { 11016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 11116d9e3a6SLisandro Dalcin PetscErrorCode ierr; 11216d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 11316d9e3a6SLisandro Dalcin HYPRE_ParVector bv,xv; 11416d9e3a6SLisandro Dalcin PetscInt bs; 11516d9e3a6SLisandro Dalcin 11616d9e3a6SLisandro Dalcin PetscFunctionBegin; 11716d9e3a6SLisandro Dalcin if (!jac->hypre_type) { 11802a17cd4SBarry Smith ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr); 11916d9e3a6SLisandro Dalcin } 1205f5c5b43SBarry Smith 1215f5c5b43SBarry Smith if (pc->setupcalled) { 1225f5c5b43SBarry Smith /* always destroy the old matrix and create a new memory; 1235f5c5b43SBarry Smith hope this does not churn the memory too much. The problem 1245f5c5b43SBarry Smith is I do not know if it is possible to put the matrix back to 1255f5c5b43SBarry Smith its initial state so that we can directly copy the values 1265f5c5b43SBarry Smith the second time through. */ 127fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij)); 1285f5c5b43SBarry Smith jac->ij = 0; 12916d9e3a6SLisandro Dalcin } 1305f5c5b43SBarry Smith 13116d9e3a6SLisandro Dalcin if (!jac->ij) { /* create the matrix the first time through */ 13216d9e3a6SLisandro Dalcin ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr); 13316d9e3a6SLisandro Dalcin } 13416d9e3a6SLisandro Dalcin if (!jac->b) { /* create the vectors the first time through */ 13516d9e3a6SLisandro Dalcin Vec x,b; 1362a7a6963SBarry Smith ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr); 13716d9e3a6SLisandro Dalcin ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr); 13816d9e3a6SLisandro Dalcin ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr); 1396bf464f9SBarry Smith ierr = VecDestroy(&x);CHKERRQ(ierr); 1406bf464f9SBarry Smith ierr = VecDestroy(&b);CHKERRQ(ierr); 14116d9e3a6SLisandro Dalcin } 1425f5c5b43SBarry Smith 14316d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 14416d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 14516d9e3a6SLisandro Dalcin ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 1462fa5cd67SKarl Rupp if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs)); 1474cb006feSStefano Zampini } 1484cb006feSStefano Zampini /* special case for AMS */ 1494cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 1504cb006feSStefano Zampini if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either coordinate vectors via PCSetCoordinates() or edge constant vectors via PCHYPRESetEdgeConstantVectors()"); 1514cb006feSStefano Zampini if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient"); 1524cb006feSStefano Zampini } 15316d9e3a6SLisandro Dalcin ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr); 154fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 155fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv)); 156fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv)); 157fd3f9acdSBarry Smith PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr);); 15816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 15916d9e3a6SLisandro Dalcin } 16016d9e3a6SLisandro Dalcin 16116d9e3a6SLisandro Dalcin /* 16216d9e3a6SLisandro Dalcin Replaces the address where the HYPRE vector points to its data with the address of 16316d9e3a6SLisandro Dalcin PETSc's data. Saves the old address so it can be reset when we are finished with it. 16416d9e3a6SLisandro Dalcin Allows use to get the data into a HYPRE vector without the cost of memcopies 16516d9e3a6SLisandro Dalcin */ 16616d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \ 16716d9e3a6SLisandro Dalcin hypre_ParVector *par_vector = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \ 16816d9e3a6SLisandro Dalcin hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); \ 16916d9e3a6SLisandro Dalcin savedvalue = local_vector->data; \ 1700ad7597dSKarl Rupp local_vector->data = newvalue; \ 1710ad7597dSKarl Rupp } 17216d9e3a6SLisandro Dalcin 17316d9e3a6SLisandro Dalcin #undef __FUNCT__ 17416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE" 17516d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x) 17616d9e3a6SLisandro Dalcin { 17716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 17816d9e3a6SLisandro Dalcin PetscErrorCode ierr; 17916d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 180*d9ca1df4SBarry Smith PetscScalar *xv; 181*d9ca1df4SBarry Smith const PetscScalar *bv,*sbv; 18216d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 183*d9ca1df4SBarry Smith PetscScalar *sxv; 1844ddd07fcSJed Brown PetscInt hierr; 18516d9e3a6SLisandro Dalcin 18616d9e3a6SLisandro Dalcin PetscFunctionBegin; 187dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 18816d9e3a6SLisandro Dalcin if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);} 189*d9ca1df4SBarry Smith ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr); 19016d9e3a6SLisandro Dalcin ierr = VecGetArray(x,&xv);CHKERRQ(ierr); 191*d9ca1df4SBarry Smith HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv); 19216d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,xv,sxv); 19316d9e3a6SLisandro Dalcin 194fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 195fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv)); 196fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv)); 197fd3f9acdSBarry Smith PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv); 19865e19b50SBarry Smith if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr); 199fd3f9acdSBarry Smith if (hierr) hypre__global_error = 0;); 20016d9e3a6SLisandro Dalcin 201*d9ca1df4SBarry Smith HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv); 20216d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,sxv,xv); 20316d9e3a6SLisandro Dalcin ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr); 204*d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr); 20516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 20616d9e3a6SLisandro Dalcin } 20716d9e3a6SLisandro Dalcin 20816d9e3a6SLisandro Dalcin #undef __FUNCT__ 20916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE" 21016d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc) 21116d9e3a6SLisandro Dalcin { 21216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 21316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 21416d9e3a6SLisandro Dalcin 21516d9e3a6SLisandro Dalcin PetscFunctionBegin; 216fd3f9acdSBarry Smith if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij)); 217fd3f9acdSBarry Smith if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b)); 218fd3f9acdSBarry Smith if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x)); 2194cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); 2204cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); 2214cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); 2224cb006feSStefano Zampini if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); 2234cb006feSStefano Zampini if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); 2244cb006feSStefano Zampini if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); 2254cb006feSStefano Zampini if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); 2264cb006feSStefano Zampini if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); 2274cb006feSStefano Zampini if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); 228226b0620SJed Brown if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr);); 229503cfb0cSBarry Smith ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr); 23016d9e3a6SLisandro Dalcin if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);} 231c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 23216d9e3a6SLisandro Dalcin 23316d9e3a6SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr); 234bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr); 235bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr); 2364cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr); 2374cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2384cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr); 2394cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr); 2404cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr); 24116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 24216d9e3a6SLisandro Dalcin } 24316d9e3a6SLisandro Dalcin 24416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 24516d9e3a6SLisandro Dalcin #undef __FUNCT__ 24616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut" 2478c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc) 24816d9e3a6SLisandro Dalcin { 24916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 25016d9e3a6SLisandro Dalcin PetscErrorCode ierr; 251ace3abfcSBarry Smith PetscBool flag; 25216d9e3a6SLisandro Dalcin 25316d9e3a6SLisandro Dalcin PetscFunctionBegin; 254e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr); 25516d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr); 256fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter)); 25716d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr); 258fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol)); 25916d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr); 260fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize)); 26116d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 26216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 26316d9e3a6SLisandro Dalcin } 26416d9e3a6SLisandro Dalcin 26516d9e3a6SLisandro Dalcin #undef __FUNCT__ 26616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut" 26716d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer) 26816d9e3a6SLisandro Dalcin { 26916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 27016d9e3a6SLisandro Dalcin PetscErrorCode ierr; 271ace3abfcSBarry Smith PetscBool iascii; 27216d9e3a6SLisandro Dalcin 27316d9e3a6SLisandro Dalcin PetscFunctionBegin; 274251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 27516d9e3a6SLisandro Dalcin if (iascii) { 27616d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut preconditioning\n");CHKERRQ(ierr); 27716d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 27816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr); 27916d9e3a6SLisandro Dalcin } else { 28016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr); 28116d9e3a6SLisandro Dalcin } 28216d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 28357622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr); 28416d9e3a6SLisandro Dalcin } else { 28516d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr); 28616d9e3a6SLisandro Dalcin } 28716d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 28816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr); 28916d9e3a6SLisandro Dalcin } else { 29016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default factor row size \n");CHKERRQ(ierr); 29116d9e3a6SLisandro Dalcin } 29216d9e3a6SLisandro Dalcin } 29316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 29416d9e3a6SLisandro Dalcin } 29516d9e3a6SLisandro Dalcin 29616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 29716d9e3a6SLisandro Dalcin 29816d9e3a6SLisandro Dalcin #undef __FUNCT__ 29916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG" 30016d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x) 30116d9e3a6SLisandro Dalcin { 30216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 30316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 30416d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 305*d9ca1df4SBarry Smith PetscScalar *xv; 306*d9ca1df4SBarry Smith const PetscScalar *bv; 30716d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 30816d9e3a6SLisandro Dalcin PetscScalar *sbv,*sxv; 3094ddd07fcSJed Brown PetscInt hierr; 31016d9e3a6SLisandro Dalcin 31116d9e3a6SLisandro Dalcin PetscFunctionBegin; 312dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 31316d9e3a6SLisandro Dalcin ierr = VecSet(x,0.0);CHKERRQ(ierr); 314*d9ca1df4SBarry Smith ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr); 31516d9e3a6SLisandro Dalcin ierr = VecGetArray(x,&xv);CHKERRQ(ierr); 316*d9ca1df4SBarry Smith HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv); 31716d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,xv,sxv); 31816d9e3a6SLisandro Dalcin 319fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 320fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv)); 321fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv)); 32216d9e3a6SLisandro Dalcin 32316d9e3a6SLisandro Dalcin hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv); 32416d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 325e32f2f54SBarry Smith if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr); 32616d9e3a6SLisandro Dalcin if (hierr) hypre__global_error = 0; 32716d9e3a6SLisandro Dalcin 32816d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,sbv,bv); 32916d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,sxv,xv); 33016d9e3a6SLisandro Dalcin ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr); 331*d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr); 33216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 33316d9e3a6SLisandro Dalcin } 33416d9e3a6SLisandro Dalcin 335a669f990SJed Brown /* static array length */ 336a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0])) 337a669f990SJed Brown 33816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"","V","W"}; 3390f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"}; 34016d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"}; 34165de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 34265de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[] = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi", 34365de4495SJed Brown "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi", 34465de4495SJed Brown "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination", 34565de4495SJed Brown "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */, 34665de4495SJed Brown "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"}; 3470f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[] = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i", 3480f1074feSSatish Balay "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"}; 34916d9e3a6SLisandro Dalcin #undef __FUNCT__ 35016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG" 3518c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc) 35216d9e3a6SLisandro Dalcin { 35316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 35416d9e3a6SLisandro Dalcin PetscErrorCode ierr; 3554ddd07fcSJed Brown PetscInt n,indx,level; 356ace3abfcSBarry Smith PetscBool flg, tmp_truth; 35716d9e3a6SLisandro Dalcin double tmpdbl, twodbl[2]; 35816d9e3a6SLisandro Dalcin 35916d9e3a6SLisandro Dalcin PetscFunctionBegin; 360e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr); 3614336a9eeSBarry Smith ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr); 36216d9e3a6SLisandro Dalcin if (flg) { 3634336a9eeSBarry Smith jac->cycletype = indx+1; 364fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype)); 36516d9e3a6SLisandro Dalcin } 36616d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr); 36716d9e3a6SLisandro Dalcin if (flg) { 368ce94432eSBarry Smith if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels); 369fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels)); 37016d9e3a6SLisandro Dalcin } 37116d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr); 37216d9e3a6SLisandro Dalcin if (flg) { 373ce94432eSBarry Smith if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter); 374fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 37516d9e3a6SLisandro Dalcin } 3760f1074feSSatish Balay ierr = PetscOptionsScalar("-pc_hypre_boomeramg_tol","Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)","None",jac->tol,&jac->tol,&flg);CHKERRQ(ierr); 37716d9e3a6SLisandro Dalcin if (flg) { 37857622a8eSBarry Smith if (jac->tol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %g must be greater than or equal to zero",(double)jac->tol); 379fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 38016d9e3a6SLisandro Dalcin } 38116d9e3a6SLisandro Dalcin 3820f1074feSSatish Balay ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr); 38316d9e3a6SLisandro Dalcin if (flg) { 38457622a8eSBarry Smith if (jac->truncfactor < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %g must be great than or equal zero",(double)jac->truncfactor); 385fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor)); 38616d9e3a6SLisandro Dalcin } 38716d9e3a6SLisandro Dalcin 3880f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_P_max","Max elements per row for interpolation operator (0=unlimited)","None",jac->pmax,&jac->pmax,&flg);CHKERRQ(ierr); 3890f1074feSSatish Balay if (flg) { 39057622a8eSBarry Smith if (jac->pmax < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %g must be greater than or equal to zero",(double)jac->pmax); 391fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax)); 3920f1074feSSatish Balay } 3930f1074feSSatish Balay 3940f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr); 3950f1074feSSatish Balay if (flg) { 39657622a8eSBarry Smith if (jac->agg_nl < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %g must be greater than or equal to zero",(double)jac->agg_nl); 3970f1074feSSatish Balay 398fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl)); 3990f1074feSSatish Balay } 4000f1074feSSatish Balay 4010f1074feSSatish Balay 4020f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_num_paths","Number of paths for aggressive coarsening","None",jac->agg_num_paths,&jac->agg_num_paths,&flg);CHKERRQ(ierr); 4030f1074feSSatish Balay if (flg) { 40457622a8eSBarry Smith if (jac->agg_num_paths < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %g must be greater than or equal to 1",(double)jac->agg_num_paths); 4050f1074feSSatish Balay 406fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths)); 4070f1074feSSatish Balay } 4080f1074feSSatish Balay 4090f1074feSSatish Balay 41016d9e3a6SLisandro Dalcin ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr); 41116d9e3a6SLisandro Dalcin if (flg) { 41257622a8eSBarry Smith if (jac->strongthreshold < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %g must be great than or equal zero",(double)jac->strongthreshold); 413fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold)); 41416d9e3a6SLisandro Dalcin } 41516d9e3a6SLisandro Dalcin ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr); 41616d9e3a6SLisandro Dalcin if (flg) { 41757622a8eSBarry Smith if (jac->maxrowsum < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be greater than zero",(double)jac->maxrowsum); 41857622a8eSBarry Smith if (jac->maxrowsum > 1.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be less than or equal one",(double)jac->maxrowsum); 419fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum)); 42016d9e3a6SLisandro Dalcin } 42116d9e3a6SLisandro Dalcin 42216d9e3a6SLisandro Dalcin /* Grid sweeps */ 4230f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_all","Number of sweeps for the up and down grid levels","None",jac->gridsweeps[0],&indx,&flg);CHKERRQ(ierr); 42416d9e3a6SLisandro Dalcin if (flg) { 425fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx)); 42616d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 42716d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 4280f1074feSSatish Balay jac->gridsweeps[1] = indx; 4290f1074feSSatish Balay /*defaults coarse to 1 */ 4300f1074feSSatish Balay jac->gridsweeps[2] = 1; 43116d9e3a6SLisandro Dalcin } 4320f1074feSSatish Balay 4330f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr); 43416d9e3a6SLisandro Dalcin if (flg) { 435fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1)); 4360f1074feSSatish Balay jac->gridsweeps[0] = indx; 43716d9e3a6SLisandro Dalcin } 43816d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr); 43916d9e3a6SLisandro Dalcin if (flg) { 440fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2)); 4410f1074feSSatish Balay jac->gridsweeps[1] = indx; 44216d9e3a6SLisandro Dalcin } 4430f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr); 44416d9e3a6SLisandro Dalcin if (flg) { 445fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3)); 4460f1074feSSatish Balay jac->gridsweeps[2] = indx; 44716d9e3a6SLisandro Dalcin } 44816d9e3a6SLisandro Dalcin 44916d9e3a6SLisandro Dalcin /* Relax type */ 450a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 45116d9e3a6SLisandro Dalcin if (flg) { 4520f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 453fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx)); 4540f1074feSSatish Balay /* by default, coarse type set to 9 */ 4550f1074feSSatish Balay jac->relaxtype[2] = 9; 4560f1074feSSatish Balay 45716d9e3a6SLisandro Dalcin } 458a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 45916d9e3a6SLisandro Dalcin if (flg) { 46016d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 461fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1)); 46216d9e3a6SLisandro Dalcin } 463a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 46416d9e3a6SLisandro Dalcin if (flg) { 4650f1074feSSatish Balay jac->relaxtype[1] = indx; 466fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2)); 46716d9e3a6SLisandro Dalcin } 468a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr); 46916d9e3a6SLisandro Dalcin if (flg) { 4700f1074feSSatish Balay jac->relaxtype[2] = indx; 471fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3)); 47216d9e3a6SLisandro Dalcin } 47316d9e3a6SLisandro Dalcin 47416d9e3a6SLisandro Dalcin /* Relaxation Weight */ 47516d9e3a6SLisandro Dalcin ierr = 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);CHKERRQ(ierr); 47616d9e3a6SLisandro Dalcin if (flg) { 477fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl)); 47816d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 47916d9e3a6SLisandro Dalcin } 48016d9e3a6SLisandro Dalcin 48116d9e3a6SLisandro Dalcin n = 2; 48216d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 48316d9e3a6SLisandro Dalcin ierr = PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level","Set the relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg);CHKERRQ(ierr); 48416d9e3a6SLisandro Dalcin if (flg) { 48516d9e3a6SLisandro Dalcin if (n == 2) { 48616d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 487fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx)); 488ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight level: you must provide 2 values separated by a comma (and no space), you provided %d",n); 48916d9e3a6SLisandro Dalcin } 49016d9e3a6SLisandro Dalcin 49116d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 49216d9e3a6SLisandro Dalcin ierr = 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);CHKERRQ(ierr); 49316d9e3a6SLisandro Dalcin if (flg) { 494fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl)); 49516d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 49616d9e3a6SLisandro Dalcin } 49716d9e3a6SLisandro Dalcin 49816d9e3a6SLisandro Dalcin n = 2; 49916d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 50016d9e3a6SLisandro Dalcin ierr = PetscOptionsRealArray("-pc_hypre_boomeramg_outer_relax_weight_level","Set the outer relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg);CHKERRQ(ierr); 50116d9e3a6SLisandro Dalcin if (flg) { 50216d9e3a6SLisandro Dalcin if (n == 2) { 50316d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 504fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx)); 505ce94432eSBarry Smith } else SETERRQ1(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 %d",n); 50616d9e3a6SLisandro Dalcin } 50716d9e3a6SLisandro Dalcin 50816d9e3a6SLisandro Dalcin /* the Relax Order */ 509acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 51016d9e3a6SLisandro Dalcin 5118afaa268SBarry Smith if (flg && tmp_truth) { 51216d9e3a6SLisandro Dalcin jac->relaxorder = 0; 513fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder)); 51416d9e3a6SLisandro Dalcin } 515a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr); 51616d9e3a6SLisandro Dalcin if (flg) { 51716d9e3a6SLisandro Dalcin jac->measuretype = indx; 518fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype)); 51916d9e3a6SLisandro Dalcin } 5200f1074feSSatish Balay /* update list length 3/07 */ 521a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr); 52216d9e3a6SLisandro Dalcin if (flg) { 52316d9e3a6SLisandro Dalcin jac->coarsentype = indx; 524fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype)); 52516d9e3a6SLisandro Dalcin } 5260f1074feSSatish Balay 5270f1074feSSatish Balay /* new 3/07 */ 528a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr); 5290f1074feSSatish Balay if (flg) { 5300f1074feSSatish Balay jac->interptype = indx; 531fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype)); 5320f1074feSSatish Balay } 5330f1074feSSatish Balay 534b96a4a96SBarry Smith ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr); 53516d9e3a6SLisandro Dalcin if (flg) { 536b96a4a96SBarry Smith level = 3; 5370298fd71SBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr); 5382fa5cd67SKarl Rupp 539b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 540fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level)); 5412ae77aedSBarry Smith } 5422ae77aedSBarry Smith 543b96a4a96SBarry Smith ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr); 5442ae77aedSBarry Smith if (flg) { 545b96a4a96SBarry Smith level = 3; 5460298fd71SBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr); 5472fa5cd67SKarl Rupp 548b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 549fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level)); 55016d9e3a6SLisandro Dalcin } 5518f87f92bSBarry Smith 5528afaa268SBarry Smith ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 5538f87f92bSBarry Smith if (flg && tmp_truth) { 5548f87f92bSBarry Smith jac->nodal_coarsen = 1; 555fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1)); 5568f87f92bSBarry Smith } 5578f87f92bSBarry Smith 558acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 5598f87f92bSBarry Smith if (flg && tmp_truth) { 5608f87f92bSBarry Smith PetscInt tmp_int; 5618f87f92bSBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr); 5628f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 563fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6)); 564fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1)); 565fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0)); 566fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels)); 5678f87f92bSBarry Smith } 5688f87f92bSBarry Smith 56916d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 57016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 57116d9e3a6SLisandro Dalcin } 57216d9e3a6SLisandro Dalcin 57316d9e3a6SLisandro Dalcin #undef __FUNCT__ 57416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG" 575ace3abfcSBarry 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) 57616d9e3a6SLisandro Dalcin { 57716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 57816d9e3a6SLisandro Dalcin PetscErrorCode ierr; 5794ddd07fcSJed Brown PetscInt oits; 58016d9e3a6SLisandro Dalcin 58116d9e3a6SLisandro Dalcin PetscFunctionBegin; 582dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 583fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter)); 584fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol)); 58516d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 58616d9e3a6SLisandro Dalcin ierr = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr); 58716d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 5888b1f7689SBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits)); 5894d0a8057SBarry Smith *outits = oits; 5904d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 5914d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 592fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 593fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 59416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 59516d9e3a6SLisandro Dalcin } 59616d9e3a6SLisandro Dalcin 59716d9e3a6SLisandro Dalcin 59816d9e3a6SLisandro Dalcin #undef __FUNCT__ 59916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG" 60016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer) 60116d9e3a6SLisandro Dalcin { 60216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 60316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 604ace3abfcSBarry Smith PetscBool iascii; 60516d9e3a6SLisandro Dalcin 60616d9e3a6SLisandro Dalcin PetscFunctionBegin; 607251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 60816d9e3a6SLisandro Dalcin if (iascii) { 60916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr); 61016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr); 61116d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr); 61216d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr); 61357622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr); 61457622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr); 61557622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr); 6160f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr); 6170f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr); 6180f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr); 6190f1074feSSatish Balay 62057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr); 62116d9e3a6SLisandro Dalcin 6220f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps down %d\n",jac->gridsweeps[0]);CHKERRQ(ierr); 6230f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps up %d\n",jac->gridsweeps[1]);CHKERRQ(ierr); 6240f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps on coarse %d\n",jac->gridsweeps[2]);CHKERRQ(ierr); 62516d9e3a6SLisandro Dalcin 6260f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax down %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr); 6270f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax up %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr); 6280f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax on coarse %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr); 62916d9e3a6SLisandro Dalcin 63057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax weight (all) %g\n",(double)jac->relaxweight);CHKERRQ(ierr); 63157622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr); 63216d9e3a6SLisandro Dalcin 63316d9e3a6SLisandro Dalcin if (jac->relaxorder) { 63416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr); 63516d9e3a6SLisandro Dalcin } else { 63616d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr); 63716d9e3a6SLisandro Dalcin } 63816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Measure type %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr); 63916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Coarsen type %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr); 6400f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation type %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr); 6418f87f92bSBarry Smith if (jac->nodal_coarsen) { 6428f87f92bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr); 6438f87f92bSBarry Smith } 6448f87f92bSBarry Smith if (jac->nodal_relax) { 6458f87f92bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr); 6468f87f92bSBarry Smith } 64716d9e3a6SLisandro Dalcin } 64816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 64916d9e3a6SLisandro Dalcin } 65016d9e3a6SLisandro Dalcin 65116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 65216d9e3a6SLisandro Dalcin #undef __FUNCT__ 65316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails" 6548c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc) 65516d9e3a6SLisandro Dalcin { 65616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 65716d9e3a6SLisandro Dalcin PetscErrorCode ierr; 6584ddd07fcSJed Brown PetscInt indx; 659ace3abfcSBarry Smith PetscBool flag; 66016d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"}; 66116d9e3a6SLisandro Dalcin 66216d9e3a6SLisandro Dalcin PetscFunctionBegin; 663e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr); 66416d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr); 66516d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr); 6662fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels)); 66716d9e3a6SLisandro Dalcin 66816d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr); 6692fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter)); 67016d9e3a6SLisandro Dalcin 67116d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr); 6722fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal)); 67316d9e3a6SLisandro Dalcin 674acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr); 6752fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging)); 67616d9e3a6SLisandro Dalcin 677acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr); 6782fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse)); 67916d9e3a6SLisandro Dalcin 680a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr); 68116d9e3a6SLisandro Dalcin if (flag) { 68216d9e3a6SLisandro Dalcin jac->symt = indx; 683fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt)); 68416d9e3a6SLisandro Dalcin } 68516d9e3a6SLisandro Dalcin 68616d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 68716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 68816d9e3a6SLisandro Dalcin } 68916d9e3a6SLisandro Dalcin 69016d9e3a6SLisandro Dalcin #undef __FUNCT__ 69116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails" 69216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer) 69316d9e3a6SLisandro Dalcin { 69416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 69516d9e3a6SLisandro Dalcin PetscErrorCode ierr; 696ace3abfcSBarry Smith PetscBool iascii; 69716d9e3a6SLisandro Dalcin const char *symt = 0;; 69816d9e3a6SLisandro Dalcin 69916d9e3a6SLisandro Dalcin PetscFunctionBegin; 700251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 70116d9e3a6SLisandro Dalcin if (iascii) { 70216d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails preconditioning\n");CHKERRQ(ierr); 70316d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr); 70457622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr); 70557622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr); 70657622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr); 707ace3abfcSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr); 708ace3abfcSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr); 7092fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 7102fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 7112fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 712ce94432eSBarry Smith else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt); 71316d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr); 71416d9e3a6SLisandro Dalcin } 71516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 71616d9e3a6SLisandro Dalcin } 7174cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/ 7184cb006feSStefano Zampini #undef __FUNCT__ 7194cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS" 7209fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc) 7214cb006feSStefano Zampini { 7224cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 7234cb006feSStefano Zampini PetscErrorCode ierr; 7244cb006feSStefano Zampini PetscInt n; 7254cb006feSStefano Zampini PetscBool flag,flag2,flag3,flag4; 7264cb006feSStefano Zampini 7274cb006feSStefano Zampini PetscFunctionBegin; 7289fa463a7SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr); 7294cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->ams_print,&jac->ams_print,&flag);CHKERRQ(ierr); 7304cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print)); 7314cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->ams_max_iter,&jac->ams_max_iter,&flag);CHKERRQ(ierr); 7324cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter)); 7334cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_cycle_type","Cycle type for AMS multigrid","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag);CHKERRQ(ierr); 7344cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type)); 7354cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->ams_tol,&jac->ams_tol,&flag);CHKERRQ(ierr); 7364cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol)); 7374cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->ams_relax_type,&jac->ams_relax_type,&flag);CHKERRQ(ierr); 7384cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->ams_relax_times,&jac->ams_relax_times,&flag2);CHKERRQ(ierr); 7394cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->ams_relax_weight,&jac->ams_relax_weight,&flag3);CHKERRQ(ierr); 7404cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->ams_omega,&jac->ams_omega,&flag4);CHKERRQ(ierr); 7414cb006feSStefano Zampini if (flag || flag2 || flag3 || flag4) { 7424cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type, 7434cb006feSStefano Zampini jac->ams_relax_times, 7444cb006feSStefano Zampini jac->ams_relax_weight, 7454cb006feSStefano Zampini jac->ams_omega)); 7464cb006feSStefano Zampini } 7474cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_amg_alpha_theta","Threshold for strong coupling of vector Poisson AMG solver","None",jac->ams_amg_alpha_theta,&jac->ams_amg_alpha_theta,&flag);CHKERRQ(ierr); 7484cb006feSStefano Zampini n = 5; 7494cb006feSStefano Zampini ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->ams_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr); 7504cb006feSStefano Zampini if (flag || flag2) { 7514cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0], /* AMG coarsen type */ 7524cb006feSStefano Zampini jac->ams_amg_alpha_opts[1], /* AMG agg_levels */ 7534cb006feSStefano Zampini jac->ams_amg_alpha_opts[2], /* AMG relax_type */ 7544cb006feSStefano Zampini jac->ams_amg_alpha_theta, 7554cb006feSStefano Zampini jac->ams_amg_alpha_opts[3], /* AMG interp_type */ 7564cb006feSStefano Zampini jac->ams_amg_alpha_opts[4])); /* AMG Pmax */ 7574cb006feSStefano Zampini } 7584cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_amg_beta_theta","Threshold for strong coupling of scalar Poisson AMG solver","None",jac->ams_amg_beta_theta,&jac->ams_amg_beta_theta,&flag);CHKERRQ(ierr); 7594cb006feSStefano Zampini n = 5; 7604cb006feSStefano Zampini ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->ams_amg_beta_opts,&n,&flag2);CHKERRQ(ierr); 7614cb006feSStefano Zampini if (flag || flag2) { 7624cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0], /* AMG coarsen type */ 7634cb006feSStefano Zampini jac->ams_amg_beta_opts[1], /* AMG agg_levels */ 7644cb006feSStefano Zampini jac->ams_amg_beta_opts[2], /* AMG relax_type */ 7654cb006feSStefano Zampini jac->ams_amg_beta_theta, 7664cb006feSStefano Zampini jac->ams_amg_beta_opts[3], /* AMG interp_type */ 7674cb006feSStefano Zampini jac->ams_amg_beta_opts[4])); /* AMG Pmax */ 7684cb006feSStefano Zampini } 7694cb006feSStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 7704cb006feSStefano Zampini PetscFunctionReturn(0); 7714cb006feSStefano Zampini } 7724cb006feSStefano Zampini 7734cb006feSStefano Zampini #undef __FUNCT__ 7744cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS" 7754cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer) 7764cb006feSStefano Zampini { 7774cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 7784cb006feSStefano Zampini PetscErrorCode ierr; 7794cb006feSStefano Zampini PetscBool iascii; 7804cb006feSStefano Zampini 7814cb006feSStefano Zampini PetscFunctionBegin; 7824cb006feSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 7834cb006feSStefano Zampini if (iascii) { 7844cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS preconditioning\n");CHKERRQ(ierr); 7854cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace iterations per application %d\n",jac->ams_max_iter);CHKERRQ(ierr); 7864cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr); 7874cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace iteration tolerance %g\n",jac->ams_tol);CHKERRQ(ierr); 7884cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother type %d\n",jac->ams_relax_type);CHKERRQ(ierr); 7894cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: number of smoothing steps %d\n",jac->ams_relax_times);CHKERRQ(ierr); 7904cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother weight %g\n",jac->ams_relax_weight);CHKERRQ(ierr); 7914cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother omega %g\n",jac->ams_omega);CHKERRQ(ierr); 7924cb006feSStefano Zampini if (jac->alpha_Poisson) { 7934cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr); 7944cb006feSStefano Zampini } else { 7954cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr); 7964cb006feSStefano Zampini } 7974cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG coarsening type %d\n",jac->ams_amg_alpha_opts[0]);CHKERRQ(ierr); 7984cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_alpha_opts[1]);CHKERRQ(ierr); 7994cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG relaxation type %d\n",jac->ams_amg_alpha_opts[2]);CHKERRQ(ierr); 8004cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG interpolation type %d\n",jac->ams_amg_alpha_opts[3]);CHKERRQ(ierr); 8014cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_alpha_opts[4]);CHKERRQ(ierr); 8024cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG strength threshold %g\n",jac->ams_amg_alpha_theta);CHKERRQ(ierr); 8034cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 8044cb006feSStefano Zampini if (jac->beta_Poisson) { 8054cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr); 8064cb006feSStefano Zampini } else { 8074cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr); 8084cb006feSStefano Zampini } 8094cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG coarsening type %d\n",jac->ams_amg_beta_opts[0]);CHKERRQ(ierr); 8104cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_beta_opts[1]);CHKERRQ(ierr); 8114cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG relaxation type %d\n",jac->ams_amg_beta_opts[2]);CHKERRQ(ierr); 8124cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG interpolation type %d\n",jac->ams_amg_beta_opts[3]);CHKERRQ(ierr); 8134cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_beta_opts[4]);CHKERRQ(ierr); 8144cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG strength threshold %g\n",jac->ams_amg_beta_theta);CHKERRQ(ierr); 8154cb006feSStefano Zampini } 8164cb006feSStefano Zampini } 8174cb006feSStefano Zampini PetscFunctionReturn(0); 8184cb006feSStefano Zampini } 8194cb006feSStefano Zampini 8204cb006feSStefano Zampini #undef __FUNCT__ 8214cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE_AMS" 8224cb006feSStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE_AMS(PC pc, Mat G) 8234cb006feSStefano Zampini { 8244cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 8254cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_G; 8264cb006feSStefano Zampini PetscErrorCode ierr; 8274cb006feSStefano Zampini 8284cb006feSStefano Zampini PetscFunctionBegin; 8294cb006feSStefano Zampini /* throw away any discrete gradient if already set */ 8304cb006feSStefano Zampini if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); 8314cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr); 8324cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr); 8334cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G))); 8344cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr_G)); 8354cb006feSStefano Zampini PetscFunctionReturn(0); 8364cb006feSStefano Zampini } 8374cb006feSStefano Zampini 8384cb006feSStefano Zampini #undef __FUNCT__ 8394cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient" 8404cb006feSStefano Zampini /*@ 8414cb006feSStefano Zampini PCHYPRESetDiscreteGradient - Set discrete gradient matrix 8424cb006feSStefano Zampini 8434cb006feSStefano Zampini Collective on PC 8444cb006feSStefano Zampini 8454cb006feSStefano Zampini Input Parameters: 8464cb006feSStefano Zampini + pc - the preconditioning context 8474cb006feSStefano Zampini - G - the discrete gradient 8484cb006feSStefano Zampini 8494cb006feSStefano Zampini Level: intermediate 8504cb006feSStefano Zampini 8514cb006feSStefano Zampini Notes: G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 8524cb006feSStefano Zampini Each row of G has 2 nonzeros, with column indexes being the global indexes of edge's endpoints: matrix values are +1 and -1 depending on edge orientation 8534cb006feSStefano Zampini 8544cb006feSStefano Zampini .seealso: 8554cb006feSStefano Zampini @*/ 8564cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 8574cb006feSStefano Zampini { 8584cb006feSStefano Zampini PetscErrorCode ierr; 8594cb006feSStefano Zampini 8604cb006feSStefano Zampini PetscFunctionBegin; 8614cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8624cb006feSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 8634cb006feSStefano Zampini PetscCheckSameComm(pc,1,G,2); 8644cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr); 8654cb006feSStefano Zampini PetscFunctionReturn(0); 8664cb006feSStefano Zampini } 8674cb006feSStefano Zampini 8684cb006feSStefano Zampini #undef __FUNCT__ 8694cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS" 8704cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A) 8714cb006feSStefano Zampini { 8724cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 8734cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_alpha_Poisson; 8744cb006feSStefano Zampini PetscErrorCode ierr; 8754cb006feSStefano Zampini 8764cb006feSStefano Zampini PetscFunctionBegin; 8774cb006feSStefano Zampini /* throw away any matrix if already set */ 8784cb006feSStefano Zampini if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); 8794cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr); 8804cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr); 8814cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson))); 8824cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson)); 8834cb006feSStefano Zampini PetscFunctionReturn(0); 8844cb006feSStefano Zampini } 8854cb006feSStefano Zampini 8864cb006feSStefano Zampini #undef __FUNCT__ 8874cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix" 8884cb006feSStefano Zampini /*@ 8894cb006feSStefano Zampini PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix 8904cb006feSStefano Zampini 8914cb006feSStefano Zampini Collective on PC 8924cb006feSStefano Zampini 8934cb006feSStefano Zampini Input Parameters: 8944cb006feSStefano Zampini + pc - the preconditioning context 8954cb006feSStefano Zampini - A - the matrix 8964cb006feSStefano Zampini 8974cb006feSStefano Zampini Level: intermediate 8984cb006feSStefano Zampini 8994cb006feSStefano Zampini Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 9004cb006feSStefano Zampini 9014cb006feSStefano Zampini .seealso: 9024cb006feSStefano Zampini @*/ 9034cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 9044cb006feSStefano Zampini { 9054cb006feSStefano Zampini PetscErrorCode ierr; 9064cb006feSStefano Zampini 9074cb006feSStefano Zampini PetscFunctionBegin; 9084cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9094cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 9104cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 9114cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr); 9124cb006feSStefano Zampini PetscFunctionReturn(0); 9134cb006feSStefano Zampini } 9144cb006feSStefano Zampini 9154cb006feSStefano Zampini #undef __FUNCT__ 9164cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS" 9174cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A) 9184cb006feSStefano Zampini { 9194cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 9204cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_beta_Poisson; 9214cb006feSStefano Zampini PetscErrorCode ierr; 9224cb006feSStefano Zampini 9234cb006feSStefano Zampini PetscFunctionBegin; 9244cb006feSStefano Zampini if (!A) { 9254cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 9264cb006feSStefano Zampini PetscFunctionReturn(0); 9274cb006feSStefano Zampini } 9284cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 9294cb006feSStefano Zampini /* throw away any matrix if already set */ 9304cb006feSStefano Zampini if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); 9314cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr); 9324cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr); 9334cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson))); 9344cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson)); 9354cb006feSStefano Zampini PetscFunctionReturn(0); 9364cb006feSStefano Zampini } 9374cb006feSStefano Zampini 9384cb006feSStefano Zampini #undef __FUNCT__ 9394cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix" 9404cb006feSStefano Zampini /*@ 9414cb006feSStefano Zampini PCHYPRESetBetaPoissonMatrix - Set Poisson matrix 9424cb006feSStefano Zampini 9434cb006feSStefano Zampini Collective on PC 9444cb006feSStefano Zampini 9454cb006feSStefano Zampini Input Parameters: 9464cb006feSStefano Zampini + pc - the preconditioning context 9474cb006feSStefano Zampini - A - the matrix 9484cb006feSStefano Zampini 9494cb006feSStefano Zampini Level: intermediate 9504cb006feSStefano Zampini 9514cb006feSStefano Zampini Notes: A should be obtained by discretizing the Poisson problem with linear finite elements. 9524cb006feSStefano Zampini Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL. 9534cb006feSStefano Zampini 9544cb006feSStefano Zampini .seealso: 9554cb006feSStefano Zampini @*/ 9564cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 9574cb006feSStefano Zampini { 9584cb006feSStefano Zampini PetscErrorCode ierr; 9594cb006feSStefano Zampini 9604cb006feSStefano Zampini PetscFunctionBegin; 9614cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9624cb006feSStefano Zampini if (A) { 9634cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 9644cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 9654cb006feSStefano Zampini } 9664cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr); 9674cb006feSStefano Zampini PetscFunctionReturn(0); 9684cb006feSStefano Zampini } 9694cb006feSStefano Zampini 9704cb006feSStefano Zampini #undef __FUNCT__ 9714cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS" 9724cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo) 9734cb006feSStefano Zampini { 9744cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 9754cb006feSStefano Zampini HYPRE_ParVector par_ozz,par_zoz,par_zzo; 97612ddd1b6SStefano Zampini PetscInt dim; 9774cb006feSStefano Zampini PetscErrorCode ierr; 9784cb006feSStefano Zampini 9794cb006feSStefano Zampini PetscFunctionBegin; 9804cb006feSStefano Zampini /* throw away any vector if already set */ 9814cb006feSStefano Zampini if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); 9824cb006feSStefano Zampini if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); 9834cb006feSStefano Zampini if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); 9844cb006feSStefano Zampini jac->constants[0] = NULL; 9854cb006feSStefano Zampini jac->constants[1] = NULL; 9864cb006feSStefano Zampini jac->constants[2] = NULL; 9874cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr); 9884cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr); 9894cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz))); 9904cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr); 9914cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr); 9924cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz))); 99312ddd1b6SStefano Zampini dim = 2; 9944cb006feSStefano Zampini if (zzo) { 9954cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr); 9964cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr); 9974cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo))); 99812ddd1b6SStefano Zampini dim++; 9994cb006feSStefano Zampini } 10004cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo)); 100112ddd1b6SStefano Zampini PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim)); 10024cb006feSStefano Zampini PetscFunctionReturn(0); 10034cb006feSStefano Zampini } 10044cb006feSStefano Zampini 10054cb006feSStefano Zampini #undef __FUNCT__ 10064cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors" 10074cb006feSStefano Zampini /*@ 10084cb006feSStefano Zampini PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis 10094cb006feSStefano Zampini 10104cb006feSStefano Zampini Collective on PC 10114cb006feSStefano Zampini 10124cb006feSStefano Zampini Input Parameters: 10134cb006feSStefano Zampini + pc - the preconditioning context 10144cb006feSStefano Zampini - ozz - vector representing (1,0,0) (or (1,0) in 2D) 10154cb006feSStefano Zampini - zoz - vector representing (0,1,0) (or (0,1) in 2D) 10164cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 10174cb006feSStefano Zampini 10184cb006feSStefano Zampini Level: intermediate 10194cb006feSStefano Zampini 10204cb006feSStefano Zampini Notes: 10214cb006feSStefano Zampini 10224cb006feSStefano Zampini .seealso: 10234cb006feSStefano Zampini @*/ 10244cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 10254cb006feSStefano Zampini { 10264cb006feSStefano Zampini PetscErrorCode ierr; 10274cb006feSStefano Zampini 10284cb006feSStefano Zampini PetscFunctionBegin; 10294cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 10304cb006feSStefano Zampini PetscValidHeaderSpecific(ozz,VEC_CLASSID,2); 10314cb006feSStefano Zampini PetscValidHeaderSpecific(zoz,VEC_CLASSID,3); 10324cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4); 10334cb006feSStefano Zampini PetscCheckSameComm(pc,1,ozz,2); 10344cb006feSStefano Zampini PetscCheckSameComm(pc,1,zoz,3); 10354cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc,1,zzo,4); 10364cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr); 10374cb006feSStefano Zampini PetscFunctionReturn(0); 10384cb006feSStefano Zampini } 10394cb006feSStefano Zampini 10404cb006feSStefano Zampini #undef __FUNCT__ 10414cb006feSStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE_AMS" 10424cb006feSStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE_AMS(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 10434cb006feSStefano Zampini { 10444cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 10454cb006feSStefano Zampini Vec tv; 10464cb006feSStefano Zampini HYPRE_ParVector par_coords[3]; 10474cb006feSStefano Zampini PetscInt i; 10484cb006feSStefano Zampini PetscErrorCode ierr; 10494cb006feSStefano Zampini 10504cb006feSStefano Zampini PetscFunctionBegin; 10514cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 10524cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); 10534cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); 10544cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); 10554cb006feSStefano Zampini /* set problem's dimension */ 10564cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim)); 10574cb006feSStefano Zampini /* compute IJ vector for coordinates */ 10584cb006feSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr); 10594cb006feSStefano Zampini ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr); 10604cb006feSStefano Zampini ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr); 10614cb006feSStefano Zampini for (i=0;i<dim;i++) { 10624cb006feSStefano Zampini PetscScalar *array; 10634cb006feSStefano Zampini PetscInt j; 10644cb006feSStefano Zampini 10654cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr); 10664cb006feSStefano Zampini ierr = VecGetArray(tv,&array);CHKERRQ(ierr); 10674cb006feSStefano Zampini for (j=0;j<nloc;j++) { 10684cb006feSStefano Zampini array[j] = coords[j*dim+i]; 10694cb006feSStefano Zampini } 10704cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array)); 10714cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i])); 10724cb006feSStefano Zampini ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr); 10734cb006feSStefano Zampini } 10744cb006feSStefano Zampini ierr = VecDestroy(&tv);CHKERRQ(ierr); 10754cb006feSStefano Zampini /* pass parCSR vectors to AMS solver */ 10764cb006feSStefano Zampini par_coords[0] = NULL; 10774cb006feSStefano Zampini par_coords[1] = NULL; 10784cb006feSStefano Zampini par_coords[2] = NULL; 10794cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0]))); 10804cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1]))); 10814cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2]))); 10824cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,par_coords[0],par_coords[1],par_coords[2])); 10834cb006feSStefano Zampini PetscFunctionReturn(0); 10844cb006feSStefano Zampini } 10854cb006feSStefano Zampini 108616d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/ 108716d9e3a6SLisandro Dalcin 108816d9e3a6SLisandro Dalcin #undef __FUNCT__ 108916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE" 1090f7a08781SBarry Smith static PetscErrorCode PCHYPREGetType_HYPRE(PC pc,const char *name[]) 109116d9e3a6SLisandro Dalcin { 109216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 109316d9e3a6SLisandro Dalcin 109416d9e3a6SLisandro Dalcin PetscFunctionBegin; 109516d9e3a6SLisandro Dalcin *name = jac->hypre_type; 109616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 109716d9e3a6SLisandro Dalcin } 109816d9e3a6SLisandro Dalcin 109916d9e3a6SLisandro Dalcin #undef __FUNCT__ 110016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE" 1101f7a08781SBarry Smith static PetscErrorCode PCHYPRESetType_HYPRE(PC pc,const char name[]) 110216d9e3a6SLisandro Dalcin { 110316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 110416d9e3a6SLisandro Dalcin PetscErrorCode ierr; 1105ace3abfcSBarry Smith PetscBool flag; 110616d9e3a6SLisandro Dalcin 110716d9e3a6SLisandro Dalcin PetscFunctionBegin; 110816d9e3a6SLisandro Dalcin if (jac->hypre_type) { 110916d9e3a6SLisandro Dalcin ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr); 1110ce94432eSBarry Smith if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set"); 111116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 111216d9e3a6SLisandro Dalcin } else { 111316d9e3a6SLisandro Dalcin ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr); 111416d9e3a6SLisandro Dalcin } 111516d9e3a6SLisandro Dalcin 111616d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 111716d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 111816d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 111916d9e3a6SLisandro Dalcin 112016d9e3a6SLisandro Dalcin ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr); 112116d9e3a6SLisandro Dalcin if (flag) { 1122fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver)); 112316d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 112416d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 112516d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 112616d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 112716d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 112816d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 112916d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 113016d9e3a6SLisandro Dalcin } 113116d9e3a6SLisandro Dalcin ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr); 113216d9e3a6SLisandro Dalcin if (flag) { 1133fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver)); 113416d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 113516d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 113616d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 113716d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 113816d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 113916d9e3a6SLisandro Dalcin /* initialize */ 114016d9e3a6SLisandro Dalcin jac->nlevels = 1; 114116d9e3a6SLisandro Dalcin jac->threshhold = .1; 114216d9e3a6SLisandro Dalcin jac->filter = .1; 114316d9e3a6SLisandro Dalcin jac->loadbal = 0; 11442fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE; 11452fa5cd67SKarl Rupp else jac->logging = (int) PETSC_FALSE; 11462fa5cd67SKarl Rupp 114716d9e3a6SLisandro Dalcin jac->ruse = (int) PETSC_FALSE; 114816d9e3a6SLisandro Dalcin jac->symt = 0; 1149fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels)); 1150fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter)); 1151fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal)); 1152fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging)); 1153fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse)); 1154fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt)); 115516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 115616d9e3a6SLisandro Dalcin } 115716d9e3a6SLisandro Dalcin ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr); 115816d9e3a6SLisandro Dalcin if (flag) { 115916d9e3a6SLisandro Dalcin ierr = HYPRE_BoomerAMGCreate(&jac->hsolver); 116016d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 116116d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 116216d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 116316d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 116416d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 116516d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 116616d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 116716d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 116816d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 116916d9e3a6SLisandro Dalcin jac->cycletype = 1; 117016d9e3a6SLisandro Dalcin jac->maxlevels = 25; 117116d9e3a6SLisandro Dalcin jac->maxiter = 1; 11728f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 117316d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 117416d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 117516d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 117616d9e3a6SLisandro Dalcin jac->coarsentype = 6; 117716d9e3a6SLisandro Dalcin jac->measuretype = 0; 11780f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 11798f87f92bSBarry Smith jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */ 11800f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 118116d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 118216d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 118316d9e3a6SLisandro Dalcin jac->relaxorder = 1; 11840f1074feSSatish Balay jac->interptype = 0; 11850f1074feSSatish Balay jac->agg_nl = 0; 11860f1074feSSatish Balay jac->pmax = 0; 11870f1074feSSatish Balay jac->truncfactor = 0.0; 11880f1074feSSatish Balay jac->agg_num_paths = 1; 11898f87f92bSBarry Smith 11908f87f92bSBarry Smith jac->nodal_coarsen = 0; 11918f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 11928f87f92bSBarry Smith jac->nodal_relax_levels = 1; 1193fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype)); 1194fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels)); 1195fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 1196fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 1197fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor)); 1198fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold)); 1199fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum)); 1200fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype)); 1201fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype)); 1202fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder)); 1203fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype)); 1204fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl)); 1205fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax)); 1206fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths)); 1207fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0])); /*defaults coarse to 9*/ 1208fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */ 120916d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 121016d9e3a6SLisandro Dalcin } 12114cb006feSStefano Zampini ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr); 12124cb006feSStefano Zampini if (flag) { 12134cb006feSStefano Zampini ierr = HYPRE_AMSCreate(&jac->hsolver); 12144cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 12154cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 12164cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 12174cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 12184cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 12194cb006feSStefano Zampini jac->coords[0] = NULL; 12204cb006feSStefano Zampini jac->coords[1] = NULL; 12214cb006feSStefano Zampini jac->coords[2] = NULL; 12224cb006feSStefano Zampini jac->G = NULL; 12234cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 12244cb006feSStefano Zampini jac->ams_print = 0; 12254cb006feSStefano Zampini jac->ams_max_iter = 1; /* used as a preconditioner */ 12264cb006feSStefano Zampini jac->ams_cycle_type = 13; 12274cb006feSStefano Zampini jac->ams_tol = 0.; /* used as a preconditioner */ 12284cb006feSStefano Zampini /* Smoothing options */ 12294cb006feSStefano Zampini jac->ams_relax_type = 2; 12304cb006feSStefano Zampini jac->ams_relax_times = 1; 12314cb006feSStefano Zampini jac->ams_relax_weight = 1.0; 12324cb006feSStefano Zampini jac->ams_omega = 1.0; 12334cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 12344cb006feSStefano Zampini jac->ams_amg_alpha_opts[0] = 10; 12354cb006feSStefano Zampini jac->ams_amg_alpha_opts[1] = 1; 12364cb006feSStefano Zampini jac->ams_amg_alpha_opts[2] = 8; 12374cb006feSStefano Zampini jac->ams_amg_alpha_opts[3] = 6; 12384cb006feSStefano Zampini jac->ams_amg_alpha_opts[4] = 4; 12394cb006feSStefano Zampini jac->ams_amg_alpha_theta = 0.25; 12404cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 12414cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 12424cb006feSStefano Zampini jac->ams_amg_beta_opts[0] = 10; 12434cb006feSStefano Zampini jac->ams_amg_beta_opts[1] = 1; 12444cb006feSStefano Zampini jac->ams_amg_beta_opts[2] = 8; 12454cb006feSStefano Zampini jac->ams_amg_beta_opts[3] = 6; 12464cb006feSStefano Zampini jac->ams_amg_beta_opts[4] = 4; 12474cb006feSStefano Zampini jac->ams_amg_beta_theta = 0.25; 12484cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print)); 12494cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter)); 12504cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type)); 12514cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol)); 12524cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type, 12534cb006feSStefano Zampini jac->ams_relax_times, 12544cb006feSStefano Zampini jac->ams_relax_weight, 12554cb006feSStefano Zampini jac->ams_omega)); 12564cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0], /* AMG coarsen type */ 12574cb006feSStefano Zampini jac->ams_amg_alpha_opts[1], /* AMG agg_levels */ 12584cb006feSStefano Zampini jac->ams_amg_alpha_opts[2], /* AMG relax_type */ 12594cb006feSStefano Zampini jac->ams_amg_alpha_theta, 12604cb006feSStefano Zampini jac->ams_amg_alpha_opts[3], /* AMG interp_type */ 12614cb006feSStefano Zampini jac->ams_amg_alpha_opts[4])); /* AMG Pmax */ 12624cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0], /* AMG coarsen type */ 12634cb006feSStefano Zampini jac->ams_amg_beta_opts[1], /* AMG agg_levels */ 12644cb006feSStefano Zampini jac->ams_amg_beta_opts[2], /* AMG relax_type */ 12654cb006feSStefano Zampini jac->ams_amg_beta_theta, 12664cb006feSStefano Zampini jac->ams_amg_beta_opts[3], /* AMG interp_type */ 12674cb006feSStefano Zampini jac->ams_amg_beta_opts[4])); /* AMG Pmax */ 12684cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE_AMS);CHKERRQ(ierr); 12694cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE_AMS);CHKERRQ(ierr); 12704cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr); 12714cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr); 12724cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr); 12734cb006feSStefano Zampini PetscFunctionReturn(0); 12744cb006feSStefano Zampini } 1275503cfb0cSBarry Smith ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr); 12762fa5cd67SKarl Rupp 12770298fd71SBarry Smith jac->hypre_type = NULL; 127833263987SBarry Smith SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name); 127916d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 128016d9e3a6SLisandro Dalcin } 128116d9e3a6SLisandro Dalcin 128216d9e3a6SLisandro Dalcin /* 128316d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 128416d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 128516d9e3a6SLisandro Dalcin */ 128616d9e3a6SLisandro Dalcin #undef __FUNCT__ 128716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE" 12888c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc) 128916d9e3a6SLisandro Dalcin { 129016d9e3a6SLisandro Dalcin PetscErrorCode ierr; 12914ddd07fcSJed Brown PetscInt indx; 129233263987SBarry Smith const char *type[] = {"pilut","parasails","boomeramg","ams"}; 1293ace3abfcSBarry Smith PetscBool flg; 129416d9e3a6SLisandro Dalcin 129516d9e3a6SLisandro Dalcin PetscFunctionBegin; 12969fa463a7SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr); 12979c81f712SBarry Smith ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr); 129816d9e3a6SLisandro Dalcin if (flg) { 129916d9e3a6SLisandro Dalcin ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr); 130002a17cd4SBarry Smith } else { 130102a17cd4SBarry Smith ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr); 130216d9e3a6SLisandro Dalcin } 130316d9e3a6SLisandro Dalcin if (pc->ops->setfromoptions) { 13043931853cSBarry Smith ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr); 130516d9e3a6SLisandro Dalcin } 130616d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 130716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 130816d9e3a6SLisandro Dalcin } 130916d9e3a6SLisandro Dalcin 131016d9e3a6SLisandro Dalcin #undef __FUNCT__ 131116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType" 131216d9e3a6SLisandro Dalcin /*@C 131316d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 131416d9e3a6SLisandro Dalcin 131516d9e3a6SLisandro Dalcin Input Parameters: 131616d9e3a6SLisandro Dalcin + pc - the preconditioner context 131733263987SBarry Smith - name - either pilut, parasails, boomeramg, ams 131816d9e3a6SLisandro Dalcin 131916d9e3a6SLisandro Dalcin Options Database Keys: 132033263987SBarry Smith -pc_hypre_type - One of pilut, parasails, boomeramg, ams 132116d9e3a6SLisandro Dalcin 132216d9e3a6SLisandro Dalcin Level: intermediate 132316d9e3a6SLisandro Dalcin 132416d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 132516d9e3a6SLisandro Dalcin PCHYPRE 132616d9e3a6SLisandro Dalcin 132716d9e3a6SLisandro Dalcin @*/ 13287087cfbeSBarry Smith PetscErrorCode PCHYPRESetType(PC pc,const char name[]) 132916d9e3a6SLisandro Dalcin { 13304ac538c5SBarry Smith PetscErrorCode ierr; 133116d9e3a6SLisandro Dalcin 133216d9e3a6SLisandro Dalcin PetscFunctionBegin; 13330700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 133416d9e3a6SLisandro Dalcin PetscValidCharPointer(name,2); 13354ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr); 133616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 133716d9e3a6SLisandro Dalcin } 133816d9e3a6SLisandro Dalcin 133916d9e3a6SLisandro Dalcin #undef __FUNCT__ 134016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType" 134116d9e3a6SLisandro Dalcin /*@C 134216d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 134316d9e3a6SLisandro Dalcin 134416d9e3a6SLisandro Dalcin Input Parameter: 134516d9e3a6SLisandro Dalcin . pc - the preconditioner context 134616d9e3a6SLisandro Dalcin 134716d9e3a6SLisandro Dalcin Output Parameter: 134833263987SBarry Smith . name - either pilut, parasails, boomeramg, ams 134916d9e3a6SLisandro Dalcin 135016d9e3a6SLisandro Dalcin Level: intermediate 135116d9e3a6SLisandro Dalcin 135216d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC, 135316d9e3a6SLisandro Dalcin PCHYPRE 135416d9e3a6SLisandro Dalcin 135516d9e3a6SLisandro Dalcin @*/ 13567087cfbeSBarry Smith PetscErrorCode PCHYPREGetType(PC pc,const char *name[]) 135716d9e3a6SLisandro Dalcin { 13584ac538c5SBarry Smith PetscErrorCode ierr; 135916d9e3a6SLisandro Dalcin 136016d9e3a6SLisandro Dalcin PetscFunctionBegin; 13610700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 136216d9e3a6SLisandro Dalcin PetscValidPointer(name,2); 13634ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr); 136416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 136516d9e3a6SLisandro Dalcin } 136616d9e3a6SLisandro Dalcin 136716d9e3a6SLisandro Dalcin /*MC 136816d9e3a6SLisandro Dalcin PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre 136916d9e3a6SLisandro Dalcin 137016d9e3a6SLisandro Dalcin Options Database Keys: 137133263987SBarry Smith + -pc_hypre_type - One of pilut, parasails, boomeramg, ams 137216d9e3a6SLisandro Dalcin - Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX 137316d9e3a6SLisandro Dalcin preconditioner 137416d9e3a6SLisandro Dalcin 137516d9e3a6SLisandro Dalcin Level: intermediate 137616d9e3a6SLisandro Dalcin 137716d9e3a6SLisandro Dalcin Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()), 137816d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 137916d9e3a6SLisandro Dalcin or with PetscOptionsSetValue(), there are no functions to set them) 138016d9e3a6SLisandro Dalcin 138116d9e3a6SLisandro Dalcin The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations 13820f1074feSSatish Balay (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if 13830f1074feSSatish Balay -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner 13840f1074feSSatish Balay (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of 13858f87f92bSBarry Smith iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations 13860f1074feSSatish Balay and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10 13870f1074feSSatish Balay then AT MOST twenty V-cycles of boomeramg will be called. 138816d9e3a6SLisandro Dalcin 13890f1074feSSatish Balay Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation 13900f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 13910f1074feSSatish Balay Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi. 139216d9e3a6SLisandro Dalcin If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly 139316d9e3a6SLisandro Dalcin and use -ksp_max_it to control the number of V-cycles. 139416d9e3a6SLisandro Dalcin (see the PETSc FAQ.html at the PETSc website under the Documentation tab). 139516d9e3a6SLisandro Dalcin 139616d9e3a6SLisandro Dalcin 2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option 139716d9e3a6SLisandro Dalcin -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L. 139816d9e3a6SLisandro Dalcin 13999e5bc791SBarry Smith See PCPFMG for access to the hypre Struct PFMG solver 14009e5bc791SBarry Smith 140116d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 14029e5bc791SBarry Smith PCHYPRESetType(), PCPFMG 140316d9e3a6SLisandro Dalcin 140416d9e3a6SLisandro Dalcin M*/ 140516d9e3a6SLisandro Dalcin 140616d9e3a6SLisandro Dalcin #undef __FUNCT__ 140716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE" 14088cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 140916d9e3a6SLisandro Dalcin { 141016d9e3a6SLisandro Dalcin PC_HYPRE *jac; 141116d9e3a6SLisandro Dalcin PetscErrorCode ierr; 141216d9e3a6SLisandro Dalcin 141316d9e3a6SLisandro Dalcin PetscFunctionBegin; 1414b00a9115SJed Brown ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 14152fa5cd67SKarl Rupp 141616d9e3a6SLisandro Dalcin pc->data = jac; 141716d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 141816d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 141916d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 142016d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 142116d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 14220298fd71SBarry Smith jac->hypre_type = NULL; 14234cb006feSStefano Zampini jac->coords[0] = NULL; 14244cb006feSStefano Zampini jac->coords[1] = NULL; 14254cb006feSStefano Zampini jac->coords[2] = NULL; 14264cb006feSStefano Zampini jac->constants[0] = NULL; 14274cb006feSStefano Zampini jac->constants[1] = NULL; 14284cb006feSStefano Zampini jac->constants[2] = NULL; 142916d9e3a6SLisandro Dalcin /* duplicate communicator for hypre */ 1430ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr); 1431bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr); 1432bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr); 143316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 143416d9e3a6SLisandro Dalcin } 1435ebc551c0SBarry Smith 1436f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/ 1437f91d8e95SBarry Smith 1438b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */ 1439b45d2f2cSJed Brown #include <petsc-private/matimpl.h> 1440ebc551c0SBarry Smith 1441ebc551c0SBarry Smith typedef struct { 144268326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 1443f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 14449e5bc791SBarry Smith 14459e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 14464ddd07fcSJed Brown PetscInt its; 14479e5bc791SBarry Smith double tol; 14484ddd07fcSJed Brown PetscInt relax_type; 14494ddd07fcSJed Brown PetscInt rap_type; 14504ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 14514ddd07fcSJed Brown PetscInt max_levels; 1452ebc551c0SBarry Smith } PC_PFMG; 1453ebc551c0SBarry Smith 1454ebc551c0SBarry Smith #undef __FUNCT__ 1455ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG" 1456ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc) 1457ebc551c0SBarry Smith { 1458ebc551c0SBarry Smith PetscErrorCode ierr; 1459f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1460ebc551c0SBarry Smith 1461ebc551c0SBarry Smith PetscFunctionBegin; 14622fa5cd67SKarl Rupp if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver)); 1463f91d8e95SBarry Smith ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr); 1464c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 1465ebc551c0SBarry Smith PetscFunctionReturn(0); 1466ebc551c0SBarry Smith } 1467ebc551c0SBarry Smith 14689e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"}; 14699e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"}; 14709e5bc791SBarry Smith 1471ebc551c0SBarry Smith #undef __FUNCT__ 1472ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG" 1473ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer) 1474ebc551c0SBarry Smith { 1475ebc551c0SBarry Smith PetscErrorCode ierr; 1476ace3abfcSBarry Smith PetscBool iascii; 1477f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1478ebc551c0SBarry Smith 1479ebc551c0SBarry Smith PetscFunctionBegin; 1480251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 14819e5bc791SBarry Smith if (iascii) { 14829e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG preconditioning\n");CHKERRQ(ierr); 14839e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr); 14849e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr); 14859e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr); 14869e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr); 14879e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr); 14883b46a515SGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr); 14899e5bc791SBarry Smith } 1490ebc551c0SBarry Smith PetscFunctionReturn(0); 1491ebc551c0SBarry Smith } 1492ebc551c0SBarry Smith 14939e5bc791SBarry Smith 1494ebc551c0SBarry Smith #undef __FUNCT__ 1495ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG" 14968c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc) 1497ebc551c0SBarry Smith { 1498ebc551c0SBarry Smith PetscErrorCode ierr; 1499f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1500ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1501ebc551c0SBarry Smith 1502ebc551c0SBarry Smith PetscFunctionBegin; 1503e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr); 15040298fd71SBarry Smith ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr); 150568326731SBarry Smith if (flg) { 1506a0324ebeSBarry Smith int level=3; 1507fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level)); 150868326731SBarry Smith } 15090298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr); 1510fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its)); 15110298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_StructPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr); 1512fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax)); 15130298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_StructPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr); 1514fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax)); 15159e5bc791SBarry Smith 15160298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr); 1517fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels)); 15183b46a515SGlenn Hammond 15190298fd71SBarry Smith ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr); 1520fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol)); 15210298fd71SBarry Smith ierr = PetscOptionsEList("-pc_pfmg_relax_type","Relax type for the up and down cycles","HYPRE_StructPFMGSetRelaxType",PFMGRelaxType,ALEN(PFMGRelaxType),PFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr); 1522fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type)); 15230298fd71SBarry Smith ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr); 1524fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type)); 1525ebc551c0SBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 1526ebc551c0SBarry Smith PetscFunctionReturn(0); 1527ebc551c0SBarry Smith } 1528ebc551c0SBarry Smith 1529f91d8e95SBarry Smith #undef __FUNCT__ 1530f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG" 1531f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y) 1532f91d8e95SBarry Smith { 1533f91d8e95SBarry Smith PetscErrorCode ierr; 1534f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1535*d9ca1df4SBarry Smith PetscScalar *yy; 1536*d9ca1df4SBarry Smith const PetscScalar *xx; 15374ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 153868326731SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 1539f91d8e95SBarry Smith 1540f91d8e95SBarry Smith PetscFunctionBegin; 1541dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1542aa219208SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1543f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 1544f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 1545f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 1546f91d8e95SBarry Smith 1547f91d8e95SBarry Smith /* copy x values over to hypre */ 1548fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0)); 1549*d9ca1df4SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 1550*d9ca1df4SBarry Smith PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx)); 1551*d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 1552fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb)); 1553fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx)); 1554f91d8e95SBarry Smith 1555f91d8e95SBarry Smith /* copy solution values back to PETSc */ 1556f91d8e95SBarry Smith ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 15578b1f7689SBarry Smith PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy)); 1558f91d8e95SBarry Smith ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1559f91d8e95SBarry Smith PetscFunctionReturn(0); 1560f91d8e95SBarry Smith } 1561f91d8e95SBarry Smith 15629e5bc791SBarry Smith #undef __FUNCT__ 15639e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG" 1564ace3abfcSBarry 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) 15659e5bc791SBarry Smith { 15669e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG*)pc->data; 15679e5bc791SBarry Smith PetscErrorCode ierr; 15684ddd07fcSJed Brown PetscInt oits; 15699e5bc791SBarry Smith 15709e5bc791SBarry Smith PetscFunctionBegin; 1571dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1572fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its)); 1573fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol)); 15749e5bc791SBarry Smith 15759e5bc791SBarry Smith ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr); 15768b1f7689SBarry Smith PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits)); 15779e5bc791SBarry Smith *outits = oits; 15789e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 15799e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1580fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol)); 1581fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its)); 15829e5bc791SBarry Smith PetscFunctionReturn(0); 15839e5bc791SBarry Smith } 15849e5bc791SBarry Smith 15859e5bc791SBarry Smith 15863a32d3dbSGlenn Hammond #undef __FUNCT__ 15873a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG" 15883a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc) 15893a32d3dbSGlenn Hammond { 15903a32d3dbSGlenn Hammond PetscErrorCode ierr; 15913a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG*) pc->data; 15923a32d3dbSGlenn Hammond Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 1593ace3abfcSBarry Smith PetscBool flg; 15943a32d3dbSGlenn Hammond 15953a32d3dbSGlenn Hammond PetscFunctionBegin; 1596251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr); 1597ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner"); 15983a32d3dbSGlenn Hammond 15993a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 16002fa5cd67SKarl Rupp if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver)); 1601fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver)); 1602fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx)); 1603fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver)); 16043a32d3dbSGlenn Hammond PetscFunctionReturn(0); 16053a32d3dbSGlenn Hammond } 16063a32d3dbSGlenn Hammond 1607ebc551c0SBarry Smith 1608ebc551c0SBarry Smith /*MC 1609ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 1610ebc551c0SBarry Smith 1611ebc551c0SBarry Smith Level: advanced 1612ebc551c0SBarry Smith 16139e5bc791SBarry Smith Options Database: 16149e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner 16159e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid 16169e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid 16179e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG 16189e5bc791SBarry 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 16199e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 1620f91d8e95SBarry Smith 16219e5bc791SBarry Smith Notes: This is for CELL-centered descretizations 16229e5bc791SBarry Smith 16238e395302SJed Brown This must be used with the MATHYPRESTRUCT matrix type. 1624aa219208SBarry Smith This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA. 16259e5bc791SBarry Smith 16269e5bc791SBarry Smith .seealso: PCMG, MATHYPRESTRUCT 1627ebc551c0SBarry Smith M*/ 1628ebc551c0SBarry Smith 1629ebc551c0SBarry Smith #undef __FUNCT__ 1630ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG" 16318cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 1632ebc551c0SBarry Smith { 1633ebc551c0SBarry Smith PetscErrorCode ierr; 1634ebc551c0SBarry Smith PC_PFMG *ex; 1635ebc551c0SBarry Smith 1636ebc551c0SBarry Smith PetscFunctionBegin; 1637b00a9115SJed Brown ierr = PetscNew(&ex);CHKERRQ(ierr); \ 163868326731SBarry Smith pc->data = ex; 1639ebc551c0SBarry Smith 16409e5bc791SBarry Smith ex->its = 1; 16419e5bc791SBarry Smith ex->tol = 1.e-8; 16429e5bc791SBarry Smith ex->relax_type = 1; 16439e5bc791SBarry Smith ex->rap_type = 0; 16449e5bc791SBarry Smith ex->num_pre_relax = 1; 16459e5bc791SBarry Smith ex->num_post_relax = 1; 16463b46a515SGlenn Hammond ex->max_levels = 0; 16479e5bc791SBarry Smith 1648ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 1649ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 1650ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 1651f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 16529e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 165368326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 16542fa5cd67SKarl Rupp 1655ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr); 1656fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver)); 1657ebc551c0SBarry Smith PetscFunctionReturn(0); 1658ebc551c0SBarry Smith } 1659d851a50bSGlenn Hammond 1660325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/ 1661325fc9f4SBarry Smith 1662d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 1663d851a50bSGlenn Hammond typedef struct { 1664d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 1665d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 1666d851a50bSGlenn Hammond 1667d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 16684ddd07fcSJed Brown PetscInt its; 1669d851a50bSGlenn Hammond double tol; 16704ddd07fcSJed Brown PetscInt relax_type; 16714ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 1672d851a50bSGlenn Hammond } PC_SysPFMG; 1673d851a50bSGlenn Hammond 1674d851a50bSGlenn Hammond #undef __FUNCT__ 1675d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG" 1676d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc) 1677d851a50bSGlenn Hammond { 1678d851a50bSGlenn Hammond PetscErrorCode ierr; 1679d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1680d851a50bSGlenn Hammond 1681d851a50bSGlenn Hammond PetscFunctionBegin; 16822fa5cd67SKarl Rupp if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver)); 1683d851a50bSGlenn Hammond ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr); 1684c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 1685d851a50bSGlenn Hammond PetscFunctionReturn(0); 1686d851a50bSGlenn Hammond } 1687d851a50bSGlenn Hammond 1688d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"}; 1689d851a50bSGlenn Hammond 1690d851a50bSGlenn Hammond #undef __FUNCT__ 1691d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG" 1692d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer) 1693d851a50bSGlenn Hammond { 1694d851a50bSGlenn Hammond PetscErrorCode ierr; 1695ace3abfcSBarry Smith PetscBool iascii; 1696d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1697d851a50bSGlenn Hammond 1698d851a50bSGlenn Hammond PetscFunctionBegin; 1699251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1700d851a50bSGlenn Hammond if (iascii) { 1701d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr); 1702d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr); 1703d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr); 1704d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr); 1705d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr); 1706d851a50bSGlenn Hammond } 1707d851a50bSGlenn Hammond PetscFunctionReturn(0); 1708d851a50bSGlenn Hammond } 1709d851a50bSGlenn Hammond 1710d851a50bSGlenn Hammond 1711d851a50bSGlenn Hammond #undef __FUNCT__ 1712d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG" 17138c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc) 1714d851a50bSGlenn Hammond { 1715d851a50bSGlenn Hammond PetscErrorCode ierr; 1716d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1717ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1718d851a50bSGlenn Hammond 1719d851a50bSGlenn Hammond PetscFunctionBegin; 1720e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr); 17210298fd71SBarry Smith ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr); 1722d851a50bSGlenn Hammond if (flg) { 1723d851a50bSGlenn Hammond int level=3; 1724fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level)); 1725d851a50bSGlenn Hammond } 17260298fd71SBarry Smith ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr); 1727fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its)); 17280298fd71SBarry Smith ierr = PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr); 1729fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax)); 17300298fd71SBarry Smith ierr = PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr); 1731fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax)); 1732d851a50bSGlenn Hammond 17330298fd71SBarry Smith ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr); 1734fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol)); 17350298fd71SBarry Smith ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,4,SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr); 1736fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type)); 1737d851a50bSGlenn Hammond ierr = PetscOptionsTail();CHKERRQ(ierr); 1738d851a50bSGlenn Hammond PetscFunctionReturn(0); 1739d851a50bSGlenn Hammond } 1740d851a50bSGlenn Hammond 1741d851a50bSGlenn Hammond #undef __FUNCT__ 1742d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG" 1743d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y) 1744d851a50bSGlenn Hammond { 1745d851a50bSGlenn Hammond PetscErrorCode ierr; 1746d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1747*d9ca1df4SBarry Smith PetscScalar *yy; 1748*d9ca1df4SBarry Smith const PetscScalar *xx; 17494ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 1750d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 17514ddd07fcSJed Brown PetscInt ordering= mx->dofs_order; 17524ddd07fcSJed Brown PetscInt nvars = mx->nvars; 17534ddd07fcSJed Brown PetscInt part = 0; 17544ddd07fcSJed Brown PetscInt size; 17554ddd07fcSJed Brown PetscInt i; 1756d851a50bSGlenn Hammond 1757d851a50bSGlenn Hammond PetscFunctionBegin; 1758dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1759aa219208SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1760d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 1761d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 1762d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 1763d851a50bSGlenn Hammond 1764d851a50bSGlenn Hammond size = 1; 17652fa5cd67SKarl Rupp for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1); 17662fa5cd67SKarl Rupp 1767d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 1768d851a50bSGlenn Hammond if (ordering) { 1769fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0)); 1770*d9ca1df4SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 1771*d9ca1df4SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,(PetscScalar*)xx+(size*i))); 1772*d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 1773fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b)); 1774fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x)); 1775fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1776d851a50bSGlenn Hammond 1777d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 1778d851a50bSGlenn Hammond ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 17798b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i))); 1780d851a50bSGlenn Hammond ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1781a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 1782d851a50bSGlenn Hammond PetscScalar *z; 17834ddd07fcSJed Brown PetscInt j, k; 1784d851a50bSGlenn Hammond 1785785e854fSJed Brown ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr); 1786fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0)); 1787*d9ca1df4SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 1788d851a50bSGlenn Hammond 1789d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 1790d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 1791d851a50bSGlenn Hammond k= i*nvars; 17922fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j]; 1793d851a50bSGlenn Hammond } 17948b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i))); 1795*d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 1796fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b)); 1797fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1798d851a50bSGlenn Hammond 1799d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 1800d851a50bSGlenn Hammond ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 18018b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i))); 1802d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 1803d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 1804d851a50bSGlenn Hammond k= i*nvars; 18052fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i]; 1806d851a50bSGlenn Hammond } 1807d851a50bSGlenn Hammond ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1808d851a50bSGlenn Hammond ierr = PetscFree(z);CHKERRQ(ierr); 1809d851a50bSGlenn Hammond } 1810d851a50bSGlenn Hammond PetscFunctionReturn(0); 1811d851a50bSGlenn Hammond } 1812d851a50bSGlenn Hammond 1813d851a50bSGlenn Hammond #undef __FUNCT__ 1814d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG" 1815ace3abfcSBarry 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) 1816d851a50bSGlenn Hammond { 1817d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG*)pc->data; 1818d851a50bSGlenn Hammond PetscErrorCode ierr; 18194ddd07fcSJed Brown PetscInt oits; 1820d851a50bSGlenn Hammond 1821d851a50bSGlenn Hammond PetscFunctionBegin; 1822dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1823fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its)); 1824fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol)); 1825d851a50bSGlenn Hammond ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr); 18268b1f7689SBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits)); 1827d851a50bSGlenn Hammond *outits = oits; 1828d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 1829d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 1830fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol)); 1831fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its)); 1832d851a50bSGlenn Hammond PetscFunctionReturn(0); 1833d851a50bSGlenn Hammond } 1834d851a50bSGlenn Hammond 1835d851a50bSGlenn Hammond 1836d851a50bSGlenn Hammond #undef __FUNCT__ 1837d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG" 1838d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc) 1839d851a50bSGlenn Hammond { 1840d851a50bSGlenn Hammond PetscErrorCode ierr; 1841d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1842d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 1843ace3abfcSBarry Smith PetscBool flg; 1844d851a50bSGlenn Hammond 1845d851a50bSGlenn Hammond PetscFunctionBegin; 1846251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr); 1847ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner"); 1848d851a50bSGlenn Hammond 1849d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 18502fa5cd67SKarl Rupp if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver)); 1851fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver)); 1852fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver)); 1853fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1854d851a50bSGlenn Hammond PetscFunctionReturn(0); 1855d851a50bSGlenn Hammond } 1856d851a50bSGlenn Hammond 1857d851a50bSGlenn Hammond 1858d851a50bSGlenn Hammond /*MC 1859d851a50bSGlenn Hammond PCSysPFMG - the hypre SysPFMG multigrid solver 1860d851a50bSGlenn Hammond 1861d851a50bSGlenn Hammond Level: advanced 1862d851a50bSGlenn Hammond 1863d851a50bSGlenn Hammond Options Database: 1864d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner 1865d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid 1866d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid 1867d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG 1868d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel 1869d851a50bSGlenn Hammond 1870d851a50bSGlenn Hammond Notes: This is for CELL-centered descretizations 1871d851a50bSGlenn Hammond 1872f6680f47SSatish Balay This must be used with the MATHYPRESSTRUCT matrix type. 1873aa219208SBarry Smith This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA. 1874d851a50bSGlenn Hammond Also, only cell-centered variables. 1875d851a50bSGlenn Hammond 1876d851a50bSGlenn Hammond .seealso: PCMG, MATHYPRESSTRUCT 1877d851a50bSGlenn Hammond M*/ 1878d851a50bSGlenn Hammond 1879d851a50bSGlenn Hammond #undef __FUNCT__ 1880d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG" 18818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 1882d851a50bSGlenn Hammond { 1883d851a50bSGlenn Hammond PetscErrorCode ierr; 1884d851a50bSGlenn Hammond PC_SysPFMG *ex; 1885d851a50bSGlenn Hammond 1886d851a50bSGlenn Hammond PetscFunctionBegin; 1887b00a9115SJed Brown ierr = PetscNew(&ex);CHKERRQ(ierr); \ 1888d851a50bSGlenn Hammond pc->data = ex; 1889d851a50bSGlenn Hammond 1890d851a50bSGlenn Hammond ex->its = 1; 1891d851a50bSGlenn Hammond ex->tol = 1.e-8; 1892d851a50bSGlenn Hammond ex->relax_type = 1; 1893d851a50bSGlenn Hammond ex->num_pre_relax = 1; 1894d851a50bSGlenn Hammond ex->num_post_relax = 1; 1895d851a50bSGlenn Hammond 1896d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 1897d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 1898d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 1899d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 1900d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 1901d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 19022fa5cd67SKarl Rupp 1903ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr); 1904fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver)); 1905d851a50bSGlenn Hammond PetscFunctionReturn(0); 1906d851a50bSGlenn Hammond } 1907