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> 1016d9e3a6SLisandro Dalcin 1116d9e3a6SLisandro Dalcin /* 1216d9e3a6SLisandro Dalcin Private context (data structure) for the preconditioner. 1316d9e3a6SLisandro Dalcin */ 1416d9e3a6SLisandro Dalcin typedef struct { 1516d9e3a6SLisandro Dalcin HYPRE_Solver hsolver; 1616d9e3a6SLisandro Dalcin HYPRE_IJMatrix ij; 1716d9e3a6SLisandro Dalcin HYPRE_IJVector b,x; 1816d9e3a6SLisandro Dalcin 194ddd07fcSJed Brown HYPRE_Int (*destroy)(HYPRE_Solver); 204ddd07fcSJed Brown HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 214ddd07fcSJed Brown HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 2216d9e3a6SLisandro Dalcin 2316d9e3a6SLisandro Dalcin MPI_Comm comm_hypre; 2416d9e3a6SLisandro Dalcin char *hypre_type; 2516d9e3a6SLisandro Dalcin 2616d9e3a6SLisandro Dalcin /* options for Pilut and BoomerAMG*/ 274ddd07fcSJed Brown PetscInt maxiter; 2816d9e3a6SLisandro Dalcin double tol; 2916d9e3a6SLisandro Dalcin 3016d9e3a6SLisandro Dalcin /* options for Pilut */ 314ddd07fcSJed Brown PetscInt factorrowsize; 3216d9e3a6SLisandro Dalcin 3316d9e3a6SLisandro Dalcin /* options for ParaSails */ 344ddd07fcSJed Brown PetscInt nlevels; 3516d9e3a6SLisandro Dalcin double threshhold; 3616d9e3a6SLisandro Dalcin double filter; 374ddd07fcSJed Brown PetscInt sym; 3816d9e3a6SLisandro Dalcin double loadbal; 394ddd07fcSJed Brown PetscInt logging; 404ddd07fcSJed Brown PetscInt ruse; 414ddd07fcSJed Brown PetscInt symt; 4216d9e3a6SLisandro Dalcin 4316d9e3a6SLisandro Dalcin /* options for Euclid */ 44ace3abfcSBarry Smith PetscBool bjilu; 454ddd07fcSJed Brown PetscInt levels; 4616d9e3a6SLisandro Dalcin 4716d9e3a6SLisandro Dalcin /* options for Euclid and 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; 7116d9e3a6SLisandro Dalcin } PC_HYPRE; 7216d9e3a6SLisandro Dalcin 73*d2128fa2SBarry Smith #undef __FUNCT__ 74*d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver" 75*d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver) 76*d2128fa2SBarry Smith { 77*d2128fa2SBarry Smith PC_HYPRE *jac = (PC_HYPRE*)pc->data; 78*d2128fa2SBarry Smith 79*d2128fa2SBarry Smith PetscFunctionBegin; 80*d2128fa2SBarry Smith *hsolver = jac->hsolver; 81*d2128fa2SBarry Smith PetscFunctionReturn(0); 82*d2128fa2SBarry Smith } 8316d9e3a6SLisandro Dalcin 8416d9e3a6SLisandro Dalcin #undef __FUNCT__ 8516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE" 8616d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc) 8716d9e3a6SLisandro Dalcin { 8816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 8916d9e3a6SLisandro Dalcin PetscErrorCode ierr; 9016d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 9116d9e3a6SLisandro Dalcin HYPRE_ParVector bv,xv; 9216d9e3a6SLisandro Dalcin PetscInt bs; 9316d9e3a6SLisandro Dalcin 9416d9e3a6SLisandro Dalcin PetscFunctionBegin; 9516d9e3a6SLisandro Dalcin if (!jac->hypre_type) { 9602a17cd4SBarry Smith ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr); 9716d9e3a6SLisandro Dalcin } 985f5c5b43SBarry Smith 995f5c5b43SBarry Smith if (pc->setupcalled) { 1005f5c5b43SBarry Smith /* always destroy the old matrix and create a new memory; 1015f5c5b43SBarry Smith hope this does not churn the memory too much. The problem 1025f5c5b43SBarry Smith is I do not know if it is possible to put the matrix back to 1035f5c5b43SBarry Smith its initial state so that we can directly copy the values 1045f5c5b43SBarry Smith the second time through. */ 10530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJMatrixDestroy,(jac->ij)); 1065f5c5b43SBarry Smith jac->ij = 0; 10716d9e3a6SLisandro Dalcin } 1085f5c5b43SBarry Smith 10916d9e3a6SLisandro Dalcin if (!jac->ij) { /* create the matrix the first time through */ 11016d9e3a6SLisandro Dalcin ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr); 11116d9e3a6SLisandro Dalcin } 11216d9e3a6SLisandro Dalcin if (!jac->b) { /* create the vectors the first time through */ 11316d9e3a6SLisandro Dalcin Vec x,b; 11416d9e3a6SLisandro Dalcin ierr = MatGetVecs(pc->pmat,&x,&b);CHKERRQ(ierr); 11516d9e3a6SLisandro Dalcin ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr); 11616d9e3a6SLisandro Dalcin ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr); 1176bf464f9SBarry Smith ierr = VecDestroy(&x);CHKERRQ(ierr); 1186bf464f9SBarry Smith ierr = VecDestroy(&b);CHKERRQ(ierr); 11916d9e3a6SLisandro Dalcin } 1205f5c5b43SBarry Smith 12116d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 12216d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 12316d9e3a6SLisandro Dalcin ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 12416d9e3a6SLisandro Dalcin if (bs > 1) { 12530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs)); 12616d9e3a6SLisandro Dalcin } 12716d9e3a6SLisandro Dalcin }; 12816d9e3a6SLisandro Dalcin ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr); 12930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 13030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&bv)); 13130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&xv)); 13230e6f737SJed Brown PetscStackCallHypre("HYPRE_SetupXXX",(*jac->setup),(jac->hsolver,hmat,bv,xv)); 13316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 13416d9e3a6SLisandro Dalcin } 13516d9e3a6SLisandro Dalcin 13616d9e3a6SLisandro Dalcin /* 13716d9e3a6SLisandro Dalcin Replaces the address where the HYPRE vector points to its data with the address of 13816d9e3a6SLisandro Dalcin PETSc's data. Saves the old address so it can be reset when we are finished with it. 13916d9e3a6SLisandro Dalcin Allows use to get the data into a HYPRE vector without the cost of memcopies 14016d9e3a6SLisandro Dalcin */ 14116d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) {\ 14216d9e3a6SLisandro Dalcin hypre_ParVector *par_vector = (hypre_ParVector *)hypre_IJVectorObject(((hypre_IJVector*)b));\ 14316d9e3a6SLisandro Dalcin hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector);\ 14416d9e3a6SLisandro Dalcin savedvalue = local_vector->data;\ 14516d9e3a6SLisandro Dalcin local_vector->data = newvalue;} 14616d9e3a6SLisandro Dalcin 14716d9e3a6SLisandro Dalcin #undef __FUNCT__ 14816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE" 14916d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x) 15016d9e3a6SLisandro Dalcin { 15116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 15216d9e3a6SLisandro Dalcin PetscErrorCode ierr; 15316d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 15416d9e3a6SLisandro Dalcin PetscScalar *bv,*xv; 15516d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 15616d9e3a6SLisandro Dalcin PetscScalar *sbv,*sxv; 1574ddd07fcSJed Brown PetscInt hierr; 15816d9e3a6SLisandro Dalcin 15916d9e3a6SLisandro Dalcin PetscFunctionBegin; 16016d9e3a6SLisandro Dalcin if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);} 16116d9e3a6SLisandro Dalcin ierr = VecGetArray(b,&bv);CHKERRQ(ierr); 16216d9e3a6SLisandro Dalcin ierr = VecGetArray(x,&xv);CHKERRQ(ierr); 16316d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,bv,sbv); 16416d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,xv,sxv); 16516d9e3a6SLisandro Dalcin 16630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 16730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv)); 16830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv)); 16916d9e3a6SLisandro Dalcin hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv); 17065e19b50SBarry Smith if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr); 17116d9e3a6SLisandro Dalcin if (hierr) hypre__global_error = 0; 17216d9e3a6SLisandro Dalcin 17316d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,sbv,bv); 17416d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,sxv,xv); 17516d9e3a6SLisandro Dalcin ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr); 17616d9e3a6SLisandro Dalcin ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr); 17716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 17816d9e3a6SLisandro Dalcin } 17916d9e3a6SLisandro Dalcin 18016d9e3a6SLisandro Dalcin #undef __FUNCT__ 18116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE" 18216d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc) 18316d9e3a6SLisandro Dalcin { 18416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 18516d9e3a6SLisandro Dalcin PetscErrorCode ierr; 18616d9e3a6SLisandro Dalcin 18716d9e3a6SLisandro Dalcin PetscFunctionBegin; 18830e6f737SJed Brown if (jac->ij) PetscStackCallHypre(0,HYPRE_IJMatrixDestroy,(jac->ij)); 18930e6f737SJed Brown if (jac->b) PetscStackCallHypre(0,HYPRE_IJVectorDestroy,(jac->b)); 19030e6f737SJed Brown if (jac->x) PetscStackCallHypre(0,HYPRE_IJVectorDestroy,(jac->x)); 19130e6f737SJed Brown if (jac->destroy) PetscStackCallHypre("HYPRE_DistroyXXX",(*jac->destroy),(jac->hsolver)); 192503cfb0cSBarry Smith ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr); 19316d9e3a6SLisandro Dalcin if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);} 194c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 19516d9e3a6SLisandro Dalcin 19616d9e3a6SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr); 19716d9e3a6SLisandro Dalcin ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPRESetType_C","",PETSC_NULL);CHKERRQ(ierr); 19816d9e3a6SLisandro Dalcin ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPREGetType_C","",PETSC_NULL);CHKERRQ(ierr); 19916d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 20016d9e3a6SLisandro Dalcin } 20116d9e3a6SLisandro Dalcin 20216d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 20316d9e3a6SLisandro Dalcin #undef __FUNCT__ 20416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut" 20516d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc) 20616d9e3a6SLisandro Dalcin { 20716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 20816d9e3a6SLisandro Dalcin PetscErrorCode ierr; 209ace3abfcSBarry Smith PetscBool flag; 21016d9e3a6SLisandro Dalcin 21116d9e3a6SLisandro Dalcin PetscFunctionBegin; 21216d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE Pilut Options");CHKERRQ(ierr); 21316d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr); 21430e6f737SJed Brown if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter)); 21516d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr); 21630e6f737SJed Brown if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol)); 21716d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr); 21830e6f737SJed Brown if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize)); 21916d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 22016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 22116d9e3a6SLisandro Dalcin } 22216d9e3a6SLisandro Dalcin 22316d9e3a6SLisandro Dalcin #undef __FUNCT__ 22416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut" 22516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer) 22616d9e3a6SLisandro Dalcin { 22716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 22816d9e3a6SLisandro Dalcin PetscErrorCode ierr; 229ace3abfcSBarry Smith PetscBool iascii; 23016d9e3a6SLisandro Dalcin 23116d9e3a6SLisandro Dalcin PetscFunctionBegin; 232251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 23316d9e3a6SLisandro Dalcin if (iascii) { 23416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut preconditioning\n");CHKERRQ(ierr); 23516d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 23616d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr); 23716d9e3a6SLisandro Dalcin } else { 23816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr); 23916d9e3a6SLisandro Dalcin } 24016d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 24116d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: drop tolerance %G\n",jac->tol);CHKERRQ(ierr); 24216d9e3a6SLisandro Dalcin } else { 24316d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr); 24416d9e3a6SLisandro Dalcin } 24516d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 24616d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr); 24716d9e3a6SLisandro Dalcin } else { 24816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default factor row size \n");CHKERRQ(ierr); 24916d9e3a6SLisandro Dalcin } 25016d9e3a6SLisandro Dalcin } 25116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 25216d9e3a6SLisandro Dalcin } 25316d9e3a6SLisandro Dalcin 25416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 25516d9e3a6SLisandro Dalcin #undef __FUNCT__ 25616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Euclid" 25716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc) 25816d9e3a6SLisandro Dalcin { 25916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 26016d9e3a6SLisandro Dalcin PetscErrorCode ierr; 261ace3abfcSBarry Smith PetscBool flag; 262390e7148SBarry Smith char *args[8],levels[16]; 263390e7148SBarry Smith PetscInt cnt = 0; 26416d9e3a6SLisandro Dalcin 26516d9e3a6SLisandro Dalcin PetscFunctionBegin; 26616d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE Euclid Options");CHKERRQ(ierr); 26716d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_euclid_levels","Number of levels of fill ILU(k)","None",jac->levels,&jac->levels,&flag);CHKERRQ(ierr); 26816d9e3a6SLisandro Dalcin if (flag) { 26965e19b50SBarry Smith if (jac->levels < 0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be nonegative",jac->levels); 2704ddd07fcSJed Brown ierr = PetscSNPrintf(levels,sizeof levels,"%D",jac->levels);CHKERRQ(ierr); 271390e7148SBarry Smith args[cnt++] = (char*)"-level"; args[cnt++] = levels; 27216d9e3a6SLisandro Dalcin } 273acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_euclid_bj","Use block Jacobi ILU(k)","None",jac->bjilu,&jac->bjilu,PETSC_NULL);CHKERRQ(ierr); 27416d9e3a6SLisandro Dalcin if (jac->bjilu) { 275390e7148SBarry Smith args[cnt++] =(char*) "-bj"; args[cnt++] = (char*)"1"; 27616d9e3a6SLisandro Dalcin } 27716d9e3a6SLisandro Dalcin 278acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_euclid_print_statistics","Print statistics","None",jac->printstatistics,&jac->printstatistics,PETSC_NULL);CHKERRQ(ierr); 27916d9e3a6SLisandro Dalcin if (jac->printstatistics) { 280390e7148SBarry Smith args[cnt++] = (char*)"-eu_stats"; args[cnt++] = (char*)"1"; 281390e7148SBarry Smith args[cnt++] = (char*)"-eu_mem"; args[cnt++] = (char*)"1"; 28216d9e3a6SLisandro Dalcin } 28316d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 28430e6f737SJed Brown if (cnt) PetscStackCallHypre(0,HYPRE_EuclidSetParams,(jac->hsolver,cnt,args)); 28516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 28616d9e3a6SLisandro Dalcin } 28716d9e3a6SLisandro Dalcin 28816d9e3a6SLisandro Dalcin #undef __FUNCT__ 28916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Euclid" 29016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer) 29116d9e3a6SLisandro Dalcin { 29216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 29316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 294ace3abfcSBarry Smith PetscBool iascii; 29516d9e3a6SLisandro Dalcin 29616d9e3a6SLisandro Dalcin PetscFunctionBegin; 297251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 29816d9e3a6SLisandro Dalcin if (iascii) { 29916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Euclid preconditioning\n");CHKERRQ(ierr); 30016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Euclid: number of levels %d\n",jac->levels);CHKERRQ(ierr); 30116d9e3a6SLisandro Dalcin if (jac->bjilu) { 30216d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Euclid: Using block Jacobi ILU instead of parallel ILU\n");CHKERRQ(ierr); 30316d9e3a6SLisandro Dalcin } 30416d9e3a6SLisandro Dalcin } 30516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 30616d9e3a6SLisandro Dalcin } 30716d9e3a6SLisandro Dalcin 30816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 30916d9e3a6SLisandro Dalcin 31016d9e3a6SLisandro Dalcin #undef __FUNCT__ 31116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG" 31216d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x) 31316d9e3a6SLisandro Dalcin { 31416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 31516d9e3a6SLisandro Dalcin PetscErrorCode ierr; 31616d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 31716d9e3a6SLisandro Dalcin PetscScalar *bv,*xv; 31816d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 31916d9e3a6SLisandro Dalcin PetscScalar *sbv,*sxv; 3204ddd07fcSJed Brown PetscInt hierr; 32116d9e3a6SLisandro Dalcin 32216d9e3a6SLisandro Dalcin PetscFunctionBegin; 32316d9e3a6SLisandro Dalcin ierr = VecSet(x,0.0);CHKERRQ(ierr); 32416d9e3a6SLisandro Dalcin ierr = VecGetArray(b,&bv);CHKERRQ(ierr); 32516d9e3a6SLisandro Dalcin ierr = VecGetArray(x,&xv);CHKERRQ(ierr); 32616d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,bv,sbv); 32716d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,xv,sxv); 32816d9e3a6SLisandro Dalcin 32930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 33030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv)); 33130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv)); 33216d9e3a6SLisandro Dalcin 33316d9e3a6SLisandro Dalcin hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv); 33416d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 335e32f2f54SBarry Smith if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr); 33616d9e3a6SLisandro Dalcin if (hierr) hypre__global_error = 0; 33716d9e3a6SLisandro Dalcin 33816d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,sbv,bv); 33916d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,sxv,xv); 34016d9e3a6SLisandro Dalcin ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr); 34116d9e3a6SLisandro Dalcin ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr); 34216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 34316d9e3a6SLisandro Dalcin } 34416d9e3a6SLisandro Dalcin 34516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"","V","W"}; 3460f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"}; 34716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"}; 3480f1074feSSatish Balay static const char *HYPREBoomerAMGRelaxType[] = {"Jacobi","sequential-Gauss-Seidel","","SOR/Jacobi","backward-SOR/Jacobi","","symmetric-SOR/Jacobi", 3490f1074feSSatish Balay "","","Gaussian-elimination"}; 3500f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[] = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i", 3510f1074feSSatish Balay "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"}; 35216d9e3a6SLisandro Dalcin #undef __FUNCT__ 35316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG" 35416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc) 35516d9e3a6SLisandro Dalcin { 35616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 35716d9e3a6SLisandro Dalcin PetscErrorCode ierr; 3584ddd07fcSJed Brown PetscInt n,indx,level; 359ace3abfcSBarry Smith PetscBool flg, tmp_truth; 36016d9e3a6SLisandro Dalcin double tmpdbl, twodbl[2]; 36116d9e3a6SLisandro Dalcin 36216d9e3a6SLisandro Dalcin PetscFunctionBegin; 36316d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE BoomerAMG Options");CHKERRQ(ierr); 3644336a9eeSBarry Smith ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr); 36516d9e3a6SLisandro Dalcin if (flg) { 3664336a9eeSBarry Smith jac->cycletype = indx+1; 36730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype)); 36816d9e3a6SLisandro Dalcin } 36916d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr); 37016d9e3a6SLisandro Dalcin if (flg) { 37165e19b50SBarry Smith if (jac->maxlevels < 2) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels); 37230e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels)); 37316d9e3a6SLisandro Dalcin } 37416d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr); 37516d9e3a6SLisandro Dalcin if (flg) { 37665e19b50SBarry Smith if (jac->maxiter < 1) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter); 37730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 37816d9e3a6SLisandro Dalcin } 3790f1074feSSatish 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); 38016d9e3a6SLisandro Dalcin if (flg) { 38165e19b50SBarry Smith if (jac->tol < 0.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %G must be greater than or equal to zero",jac->tol); 38230e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 38316d9e3a6SLisandro Dalcin } 38416d9e3a6SLisandro Dalcin 3850f1074feSSatish Balay ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr); 38616d9e3a6SLisandro Dalcin if (flg) { 38765e19b50SBarry Smith if (jac->truncfactor < 0.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %G must be great than or equal zero",jac->truncfactor); 38830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor)); 38916d9e3a6SLisandro Dalcin } 39016d9e3a6SLisandro Dalcin 3910f1074feSSatish 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); 3920f1074feSSatish Balay if (flg) { 39365e19b50SBarry Smith if (jac->pmax < 0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"P_max %G must be greater than or equal to zero",jac->pmax); 39430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax)); 3950f1074feSSatish Balay } 3960f1074feSSatish Balay 3970f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr); 3980f1074feSSatish Balay if (flg) { 39965e19b50SBarry Smith if (jac->agg_nl < 0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %G must be greater than or equal to zero",jac->agg_nl); 4000f1074feSSatish Balay 40130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl)); 4020f1074feSSatish Balay } 4030f1074feSSatish Balay 4040f1074feSSatish Balay 4050f1074feSSatish 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); 4060f1074feSSatish Balay if (flg) { 40765e19b50SBarry Smith if (jac->agg_num_paths < 1) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %G must be greater than or equal to 1",jac->agg_num_paths); 4080f1074feSSatish Balay 40930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths)); 4100f1074feSSatish Balay } 4110f1074feSSatish Balay 4120f1074feSSatish Balay 41316d9e3a6SLisandro Dalcin ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr); 41416d9e3a6SLisandro Dalcin if (flg) { 41565e19b50SBarry Smith if (jac->strongthreshold < 0.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %G must be great than or equal zero",jac->strongthreshold); 41630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold)); 41716d9e3a6SLisandro Dalcin } 41816d9e3a6SLisandro Dalcin ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr); 41916d9e3a6SLisandro Dalcin if (flg) { 42065e19b50SBarry Smith if (jac->maxrowsum < 0.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %G must be greater than zero",jac->maxrowsum); 42165e19b50SBarry Smith if (jac->maxrowsum > 1.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %G must be less than or equal one",jac->maxrowsum); 42230e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum)); 42316d9e3a6SLisandro Dalcin } 42416d9e3a6SLisandro Dalcin 42516d9e3a6SLisandro Dalcin /* Grid sweeps */ 4260f1074feSSatish 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); 42716d9e3a6SLisandro Dalcin if (flg) { 42830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx)); 42916d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 43016d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 4310f1074feSSatish Balay jac->gridsweeps[1] = indx; 4320f1074feSSatish Balay /*defaults coarse to 1 */ 4330f1074feSSatish Balay jac->gridsweeps[2] = 1; 43416d9e3a6SLisandro Dalcin } 4350f1074feSSatish Balay 4360f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx ,&flg);CHKERRQ(ierr); 43716d9e3a6SLisandro Dalcin if (flg) { 43830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1)); 4390f1074feSSatish Balay jac->gridsweeps[0] = indx; 44016d9e3a6SLisandro Dalcin } 44116d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr); 44216d9e3a6SLisandro Dalcin if (flg) { 44330e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2)); 4440f1074feSSatish Balay jac->gridsweeps[1] = indx; 44516d9e3a6SLisandro Dalcin } 4460f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr); 44716d9e3a6SLisandro Dalcin if (flg) { 44830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3)); 4490f1074feSSatish Balay jac->gridsweeps[2] = indx; 45016d9e3a6SLisandro Dalcin } 45116d9e3a6SLisandro Dalcin 45216d9e3a6SLisandro Dalcin /* Relax type */ 4530f1074feSSatish Balay ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 45416d9e3a6SLisandro Dalcin if (flg) { 4550f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 45630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx)); 4570f1074feSSatish Balay /* by default, coarse type set to 9 */ 4580f1074feSSatish Balay jac->relaxtype[2] = 9; 4590f1074feSSatish Balay 46016d9e3a6SLisandro Dalcin } 4610f1074feSSatish Balay ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 46216d9e3a6SLisandro Dalcin if (flg) { 46316d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 46430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1)); 46516d9e3a6SLisandro Dalcin } 4660f1074feSSatish Balay ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 46716d9e3a6SLisandro Dalcin if (flg) { 4680f1074feSSatish Balay jac->relaxtype[1] = indx; 46930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2)); 47016d9e3a6SLisandro Dalcin } 47116d9e3a6SLisandro Dalcin ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr); 47216d9e3a6SLisandro Dalcin if (flg) { 4730f1074feSSatish Balay jac->relaxtype[2] = indx; 47430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3)); 47516d9e3a6SLisandro Dalcin } 47616d9e3a6SLisandro Dalcin 47716d9e3a6SLisandro Dalcin /* Relaxation Weight */ 47816d9e3a6SLisandro 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); 47916d9e3a6SLisandro Dalcin if (flg) { 48030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl)); 48116d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 48216d9e3a6SLisandro Dalcin } 48316d9e3a6SLisandro Dalcin 48416d9e3a6SLisandro Dalcin n=2; 48516d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 48616d9e3a6SLisandro 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); 48716d9e3a6SLisandro Dalcin if (flg) { 48816d9e3a6SLisandro Dalcin if (n == 2) { 48916d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 49030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx)); 49116d9e3a6SLisandro Dalcin } else { 49265e19b50SBarry Smith SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relax weight level: you must provide 2 values separated by a comma (and no space), you provided %d",n); 49316d9e3a6SLisandro Dalcin } 49416d9e3a6SLisandro Dalcin } 49516d9e3a6SLisandro Dalcin 49616d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 49716d9e3a6SLisandro 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); 49816d9e3a6SLisandro Dalcin if (flg) { 49930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetOuterWt,( jac->hsolver, tmpdbl)); 50016d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 50116d9e3a6SLisandro Dalcin } 50216d9e3a6SLisandro Dalcin 50316d9e3a6SLisandro Dalcin n=2; 50416d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 50516d9e3a6SLisandro 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); 50616d9e3a6SLisandro Dalcin if (flg) { 50716d9e3a6SLisandro Dalcin if (n == 2) { 50816d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 50930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetLevelOuterWt,( jac->hsolver, twodbl[0], indx)); 51016d9e3a6SLisandro Dalcin } else { 51165e19b50SBarry Smith SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relax weight outer level: You must provide 2 values separated by a comma (and no space), you provided %d",n); 51216d9e3a6SLisandro Dalcin } 51316d9e3a6SLisandro Dalcin } 51416d9e3a6SLisandro Dalcin 51516d9e3a6SLisandro Dalcin /* the Relax Order */ 516acfcf0e5SJed Brown ierr = PetscOptionsBool( "-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 51716d9e3a6SLisandro Dalcin 51816d9e3a6SLisandro Dalcin if (flg) { 51916d9e3a6SLisandro Dalcin jac->relaxorder = 0; 52030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder)); 52116d9e3a6SLisandro Dalcin } 52216d9e3a6SLisandro Dalcin ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,2,HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr); 52316d9e3a6SLisandro Dalcin if (flg) { 52416d9e3a6SLisandro Dalcin jac->measuretype = indx; 52530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype)); 52616d9e3a6SLisandro Dalcin } 5270f1074feSSatish Balay /* update list length 3/07 */ 5280f1074feSSatish Balay ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,11,HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr); 52916d9e3a6SLisandro Dalcin if (flg) { 53016d9e3a6SLisandro Dalcin jac->coarsentype = indx; 53130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype)); 53216d9e3a6SLisandro Dalcin } 5330f1074feSSatish Balay 5340f1074feSSatish Balay /* new 3/07 */ 5350f1074feSSatish Balay ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,14,HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr); 5360f1074feSSatish Balay if (flg) { 5370f1074feSSatish Balay jac->interptype = indx; 53830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype)); 5390f1074feSSatish Balay } 5400f1074feSSatish Balay 541b96a4a96SBarry Smith ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr); 54216d9e3a6SLisandro Dalcin if (flg) { 543b96a4a96SBarry Smith level = 3; 54416d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,PETSC_NULL);CHKERRQ(ierr); 545b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 54630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level)); 5472ae77aedSBarry Smith } 5482ae77aedSBarry Smith 549b96a4a96SBarry Smith ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr); 5502ae77aedSBarry Smith if (flg) { 551b96a4a96SBarry Smith level = 3; 5522ae77aedSBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,PETSC_NULL);CHKERRQ(ierr); 553b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 55430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level)); 55516d9e3a6SLisandro Dalcin } 5568f87f92bSBarry Smith 557acfcf0e5SJed Brown ierr = PetscOptionsBool( "-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 5588f87f92bSBarry Smith if (flg && tmp_truth) { 5598f87f92bSBarry Smith jac->nodal_coarsen = 1; 56030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetNodal,(jac->hsolver,1)); 5618f87f92bSBarry Smith } 5628f87f92bSBarry Smith 563acfcf0e5SJed Brown ierr = PetscOptionsBool( "-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 5648f87f92bSBarry Smith if (flg && tmp_truth) { 5658f87f92bSBarry Smith PetscInt tmp_int; 5668f87f92bSBarry Smith ierr = PetscOptionsInt( "-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr); 5678f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 56830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6)); 56930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1)); 57030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0)); 57130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels)); 5728f87f92bSBarry Smith } 5738f87f92bSBarry Smith 57416d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 57516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 57616d9e3a6SLisandro Dalcin } 57716d9e3a6SLisandro Dalcin 57816d9e3a6SLisandro Dalcin #undef __FUNCT__ 57916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG" 580ace3abfcSBarry 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) 58116d9e3a6SLisandro Dalcin { 58216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 58316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 5844ddd07fcSJed Brown PetscInt oits; 58516d9e3a6SLisandro Dalcin 58616d9e3a6SLisandro Dalcin PetscFunctionBegin; 58730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter)); 58830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol)); 58916d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 59016d9e3a6SLisandro Dalcin ierr = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr); 59116d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 59230e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits)); 5934d0a8057SBarry Smith *outits = oits; 5944d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 5954d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 59630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 59730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 59816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 59916d9e3a6SLisandro Dalcin } 60016d9e3a6SLisandro Dalcin 60116d9e3a6SLisandro Dalcin 60216d9e3a6SLisandro Dalcin #undef __FUNCT__ 60316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG" 60416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer) 60516d9e3a6SLisandro Dalcin { 60616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 60716d9e3a6SLisandro Dalcin PetscErrorCode ierr; 608ace3abfcSBarry Smith PetscBool iascii; 60916d9e3a6SLisandro Dalcin 61016d9e3a6SLisandro Dalcin PetscFunctionBegin; 611251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 61216d9e3a6SLisandro Dalcin if (iascii) { 61316d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr); 61416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr); 61516d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr); 61616d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr); 61716d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Convergence tolerance PER hypre call %G\n",jac->tol);CHKERRQ(ierr); 61816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Threshold for strong coupling %G\n",jac->strongthreshold);CHKERRQ(ierr); 6190f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation truncation factor %G\n",jac->truncfactor);CHKERRQ(ierr); 6200f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr); 6210f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr); 6220f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr); 6230f1074feSSatish Balay 62416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum row sums %G\n",jac->maxrowsum);CHKERRQ(ierr); 62516d9e3a6SLisandro Dalcin 6260f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps down %d\n",jac->gridsweeps[0]);CHKERRQ(ierr); 6270f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps up %d\n",jac->gridsweeps[1]);CHKERRQ(ierr); 6280f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps on coarse %d\n",jac->gridsweeps[2]);CHKERRQ(ierr); 62916d9e3a6SLisandro Dalcin 6300f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax down %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr); 6310f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax up %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr); 6320f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax on coarse %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr); 63316d9e3a6SLisandro Dalcin 63416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax weight (all) %G\n",jac->relaxweight);CHKERRQ(ierr); 63516d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Outer relax weight (all) %G\n",jac->outerrelaxweight);CHKERRQ(ierr); 63616d9e3a6SLisandro Dalcin 63716d9e3a6SLisandro Dalcin if (jac->relaxorder) { 63816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr); 63916d9e3a6SLisandro Dalcin } else { 64016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr); 64116d9e3a6SLisandro Dalcin } 64216d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Measure type %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr); 64316d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Coarsen type %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr); 6440f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation type %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr); 6458f87f92bSBarry Smith if (jac->nodal_coarsen) { 6468f87f92bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr); 6478f87f92bSBarry Smith } 6488f87f92bSBarry Smith if (jac->nodal_relax) { 6498f87f92bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr); 6508f87f92bSBarry Smith } 65116d9e3a6SLisandro Dalcin } 65216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 65316d9e3a6SLisandro Dalcin } 65416d9e3a6SLisandro Dalcin 65516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 65616d9e3a6SLisandro Dalcin #undef __FUNCT__ 65716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails" 65816d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc) 65916d9e3a6SLisandro Dalcin { 66016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 66116d9e3a6SLisandro Dalcin PetscErrorCode ierr; 6624ddd07fcSJed Brown PetscInt indx; 663ace3abfcSBarry Smith PetscBool flag; 66416d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"}; 66516d9e3a6SLisandro Dalcin 66616d9e3a6SLisandro Dalcin PetscFunctionBegin; 66716d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE ParaSails Options");CHKERRQ(ierr); 66816d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr); 66916d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr); 67016d9e3a6SLisandro Dalcin if (flag) { 67130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels)); 67216d9e3a6SLisandro Dalcin } 67316d9e3a6SLisandro Dalcin 67416d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr); 67516d9e3a6SLisandro Dalcin if (flag) { 67630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter)); 67716d9e3a6SLisandro Dalcin } 67816d9e3a6SLisandro Dalcin 67916d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr); 68016d9e3a6SLisandro Dalcin if (flag) { 68130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal)); 68216d9e3a6SLisandro Dalcin } 68316d9e3a6SLisandro Dalcin 684acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr); 68516d9e3a6SLisandro Dalcin if (flag) { 68630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging)); 68716d9e3a6SLisandro Dalcin } 68816d9e3a6SLisandro Dalcin 689acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr); 69016d9e3a6SLisandro Dalcin if (flag) { 69130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse)); 69216d9e3a6SLisandro Dalcin } 69316d9e3a6SLisandro Dalcin 69416d9e3a6SLisandro Dalcin ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,3,symtlist[0],&indx,&flag);CHKERRQ(ierr); 69516d9e3a6SLisandro Dalcin if (flag) { 69616d9e3a6SLisandro Dalcin jac->symt = indx; 69730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt)); 69816d9e3a6SLisandro Dalcin } 69916d9e3a6SLisandro Dalcin 70016d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 70116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 70216d9e3a6SLisandro Dalcin } 70316d9e3a6SLisandro Dalcin 70416d9e3a6SLisandro Dalcin #undef __FUNCT__ 70516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails" 70616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer) 70716d9e3a6SLisandro Dalcin { 70816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 70916d9e3a6SLisandro Dalcin PetscErrorCode ierr; 710ace3abfcSBarry Smith PetscBool iascii; 71116d9e3a6SLisandro Dalcin const char *symt = 0;; 71216d9e3a6SLisandro Dalcin 71316d9e3a6SLisandro Dalcin PetscFunctionBegin; 714251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 71516d9e3a6SLisandro Dalcin if (iascii) { 71616d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails preconditioning\n");CHKERRQ(ierr); 71716d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr); 71816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: threshold %G\n",jac->threshhold);CHKERRQ(ierr); 71916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: filter %G\n",jac->filter);CHKERRQ(ierr); 72016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: load balance %G\n",jac->loadbal);CHKERRQ(ierr); 721ace3abfcSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr); 722ace3abfcSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr); 72316d9e3a6SLisandro Dalcin if (!jac->symt) { 72416d9e3a6SLisandro Dalcin symt = "nonsymmetric matrix and preconditioner"; 72516d9e3a6SLisandro Dalcin } else if (jac->symt == 1) { 72616d9e3a6SLisandro Dalcin symt = "SPD matrix and preconditioner"; 72716d9e3a6SLisandro Dalcin } else if (jac->symt == 2) { 72816d9e3a6SLisandro Dalcin symt = "nonsymmetric matrix but SPD preconditioner"; 72916d9e3a6SLisandro Dalcin } else { 73065e19b50SBarry Smith SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt); 73116d9e3a6SLisandro Dalcin } 73216d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr); 73316d9e3a6SLisandro Dalcin } 73416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 73516d9e3a6SLisandro Dalcin } 73616d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/ 73716d9e3a6SLisandro Dalcin 73816d9e3a6SLisandro Dalcin EXTERN_C_BEGIN 73916d9e3a6SLisandro Dalcin #undef __FUNCT__ 74016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE" 7417087cfbeSBarry Smith PetscErrorCode PCHYPREGetType_HYPRE(PC pc,const char *name[]) 74216d9e3a6SLisandro Dalcin { 74316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 74416d9e3a6SLisandro Dalcin 74516d9e3a6SLisandro Dalcin PetscFunctionBegin; 74616d9e3a6SLisandro Dalcin *name = jac->hypre_type; 74716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 74816d9e3a6SLisandro Dalcin } 74916d9e3a6SLisandro Dalcin EXTERN_C_END 75016d9e3a6SLisandro Dalcin 75116d9e3a6SLisandro Dalcin EXTERN_C_BEGIN 75216d9e3a6SLisandro Dalcin #undef __FUNCT__ 75316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE" 7547087cfbeSBarry Smith PetscErrorCode PCHYPRESetType_HYPRE(PC pc,const char name[]) 75516d9e3a6SLisandro Dalcin { 75616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 75716d9e3a6SLisandro Dalcin PetscErrorCode ierr; 758ace3abfcSBarry Smith PetscBool flag; 75916d9e3a6SLisandro Dalcin 76016d9e3a6SLisandro Dalcin PetscFunctionBegin; 76116d9e3a6SLisandro Dalcin if (jac->hypre_type) { 76216d9e3a6SLisandro Dalcin ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr); 763e7e72b3dSBarry Smith if (!flag) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set"); 76416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 76516d9e3a6SLisandro Dalcin } else { 76616d9e3a6SLisandro Dalcin ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr); 76716d9e3a6SLisandro Dalcin } 76816d9e3a6SLisandro Dalcin 76916d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 77016d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 77116d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 77216d9e3a6SLisandro Dalcin 77316d9e3a6SLisandro Dalcin ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr); 77416d9e3a6SLisandro Dalcin if (flag) { 77530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver)); 77616d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 77716d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 77816d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 77916d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 78016d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 78116d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 78216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 78316d9e3a6SLisandro Dalcin } 78416d9e3a6SLisandro Dalcin ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr); 78516d9e3a6SLisandro Dalcin if (flag) { 78630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver)); 78716d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 78816d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 78916d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 79016d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 79116d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 79216d9e3a6SLisandro Dalcin /* initialize */ 79316d9e3a6SLisandro Dalcin jac->nlevels = 1; 79416d9e3a6SLisandro Dalcin jac->threshhold = .1; 79516d9e3a6SLisandro Dalcin jac->filter = .1; 79616d9e3a6SLisandro Dalcin jac->loadbal = 0; 79716d9e3a6SLisandro Dalcin if (PetscLogPrintInfo) { 79816d9e3a6SLisandro Dalcin jac->logging = (int) PETSC_TRUE; 79916d9e3a6SLisandro Dalcin } else { 80016d9e3a6SLisandro Dalcin jac->logging = (int) PETSC_FALSE; 80116d9e3a6SLisandro Dalcin } 80216d9e3a6SLisandro Dalcin jac->ruse = (int) PETSC_FALSE; 80316d9e3a6SLisandro Dalcin jac->symt = 0; 80430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels)); 80530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter)); 80630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal)); 80730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging)); 80830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse)); 80930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt)); 81016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 81116d9e3a6SLisandro Dalcin } 81216d9e3a6SLisandro Dalcin ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr); 81316d9e3a6SLisandro Dalcin if (flag) { 81416d9e3a6SLisandro Dalcin ierr = HYPRE_EuclidCreate(jac->comm_hypre,&jac->hsolver); 81516d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 81616d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Euclid; 81716d9e3a6SLisandro Dalcin jac->destroy = HYPRE_EuclidDestroy; 81816d9e3a6SLisandro Dalcin jac->setup = HYPRE_EuclidSetup; 81916d9e3a6SLisandro Dalcin jac->solve = HYPRE_EuclidSolve; 82016d9e3a6SLisandro Dalcin /* initialization */ 82116d9e3a6SLisandro Dalcin jac->bjilu = PETSC_FALSE; 82216d9e3a6SLisandro Dalcin jac->levels = 1; 82316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 82416d9e3a6SLisandro Dalcin } 82516d9e3a6SLisandro Dalcin ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr); 82616d9e3a6SLisandro Dalcin if (flag) { 82716d9e3a6SLisandro Dalcin ierr = HYPRE_BoomerAMGCreate(&jac->hsolver); 82816d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 82916d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 83016d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 83116d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 83216d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 83316d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 83416d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 83516d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 83616d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 83716d9e3a6SLisandro Dalcin jac->cycletype = 1; 83816d9e3a6SLisandro Dalcin jac->maxlevels = 25; 83916d9e3a6SLisandro Dalcin jac->maxiter = 1; 8408f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 84116d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 84216d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 84316d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 84416d9e3a6SLisandro Dalcin jac->coarsentype = 6; 84516d9e3a6SLisandro Dalcin jac->measuretype = 0; 8460f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 8478f87f92bSBarry Smith jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */ 8480f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 84916d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 85016d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 85116d9e3a6SLisandro Dalcin jac->relaxorder = 1; 8520f1074feSSatish Balay jac->interptype = 0; 8530f1074feSSatish Balay jac->agg_nl = 0; 8540f1074feSSatish Balay jac->pmax = 0; 8550f1074feSSatish Balay jac->truncfactor = 0.0; 8560f1074feSSatish Balay jac->agg_num_paths = 1; 8578f87f92bSBarry Smith 8588f87f92bSBarry Smith jac->nodal_coarsen = 0; 8598f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 8608f87f92bSBarry Smith jac->nodal_relax_levels = 1; 86130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype)); 86230e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels)); 86330e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 86430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 86530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor)); 86630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold)); 86730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum)); 86830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype)); 86930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype)); 87030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder)); 87130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype)); 87230e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl)); 87330e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax)); 87430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths)); 87530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0])); /*defaults coarse to 9*/ 87630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */ 87716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 87816d9e3a6SLisandro Dalcin } 879503cfb0cSBarry Smith ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr); 88016d9e3a6SLisandro Dalcin jac->hypre_type = PETSC_NULL; 88165e19b50SBarry Smith SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, euclid, boomeramg",name); 88216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 88316d9e3a6SLisandro Dalcin } 88416d9e3a6SLisandro Dalcin EXTERN_C_END 88516d9e3a6SLisandro Dalcin 88616d9e3a6SLisandro Dalcin /* 88716d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 88816d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 88916d9e3a6SLisandro Dalcin */ 89016d9e3a6SLisandro Dalcin #undef __FUNCT__ 89116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE" 89216d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE(PC pc) 89316d9e3a6SLisandro Dalcin { 89416d9e3a6SLisandro Dalcin PetscErrorCode ierr; 8954ddd07fcSJed Brown PetscInt indx; 89616d9e3a6SLisandro Dalcin const char *type[] = {"pilut","parasails","boomeramg","euclid"}; 897ace3abfcSBarry Smith PetscBool flg; 89816d9e3a6SLisandro Dalcin 89916d9e3a6SLisandro Dalcin PetscFunctionBegin; 90016d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE preconditioner options");CHKERRQ(ierr); 90102a17cd4SBarry Smith ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr); 90216d9e3a6SLisandro Dalcin if (flg) { 90316d9e3a6SLisandro Dalcin ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr); 90402a17cd4SBarry Smith } else { 90502a17cd4SBarry Smith ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr); 90616d9e3a6SLisandro Dalcin } 90716d9e3a6SLisandro Dalcin if (pc->ops->setfromoptions) { 90816d9e3a6SLisandro Dalcin ierr = pc->ops->setfromoptions(pc);CHKERRQ(ierr); 90916d9e3a6SLisandro Dalcin } 91016d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 91116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 91216d9e3a6SLisandro Dalcin } 91316d9e3a6SLisandro Dalcin 91416d9e3a6SLisandro Dalcin #undef __FUNCT__ 91516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType" 91616d9e3a6SLisandro Dalcin /*@C 91716d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 91816d9e3a6SLisandro Dalcin 91916d9e3a6SLisandro Dalcin Input Parameters: 92016d9e3a6SLisandro Dalcin + pc - the preconditioner context 92116d9e3a6SLisandro Dalcin - name - either pilut, parasails, boomeramg, euclid 92216d9e3a6SLisandro Dalcin 92316d9e3a6SLisandro Dalcin Options Database Keys: 92416d9e3a6SLisandro Dalcin -pc_hypre_type - One of pilut, parasails, boomeramg, euclid 92516d9e3a6SLisandro Dalcin 92616d9e3a6SLisandro Dalcin Level: intermediate 92716d9e3a6SLisandro Dalcin 92816d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 92916d9e3a6SLisandro Dalcin PCHYPRE 93016d9e3a6SLisandro Dalcin 93116d9e3a6SLisandro Dalcin @*/ 9327087cfbeSBarry Smith PetscErrorCode PCHYPRESetType(PC pc,const char name[]) 93316d9e3a6SLisandro Dalcin { 9344ac538c5SBarry Smith PetscErrorCode ierr; 93516d9e3a6SLisandro Dalcin 93616d9e3a6SLisandro Dalcin PetscFunctionBegin; 9370700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 93816d9e3a6SLisandro Dalcin PetscValidCharPointer(name,2); 9394ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr); 94016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 94116d9e3a6SLisandro Dalcin } 94216d9e3a6SLisandro Dalcin 94316d9e3a6SLisandro Dalcin #undef __FUNCT__ 94416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType" 94516d9e3a6SLisandro Dalcin /*@C 94616d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 94716d9e3a6SLisandro Dalcin 94816d9e3a6SLisandro Dalcin Input Parameter: 94916d9e3a6SLisandro Dalcin . pc - the preconditioner context 95016d9e3a6SLisandro Dalcin 95116d9e3a6SLisandro Dalcin Output Parameter: 95216d9e3a6SLisandro Dalcin . name - either pilut, parasails, boomeramg, euclid 95316d9e3a6SLisandro Dalcin 95416d9e3a6SLisandro Dalcin Level: intermediate 95516d9e3a6SLisandro Dalcin 95616d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC, 95716d9e3a6SLisandro Dalcin PCHYPRE 95816d9e3a6SLisandro Dalcin 95916d9e3a6SLisandro Dalcin @*/ 9607087cfbeSBarry Smith PetscErrorCode PCHYPREGetType(PC pc,const char *name[]) 96116d9e3a6SLisandro Dalcin { 9624ac538c5SBarry Smith PetscErrorCode ierr; 96316d9e3a6SLisandro Dalcin 96416d9e3a6SLisandro Dalcin PetscFunctionBegin; 9650700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 96616d9e3a6SLisandro Dalcin PetscValidPointer(name,2); 9674ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr); 96816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 96916d9e3a6SLisandro Dalcin } 97016d9e3a6SLisandro Dalcin 97116d9e3a6SLisandro Dalcin /*MC 97216d9e3a6SLisandro Dalcin PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre 97316d9e3a6SLisandro Dalcin 97416d9e3a6SLisandro Dalcin Options Database Keys: 97516d9e3a6SLisandro Dalcin + -pc_hypre_type - One of pilut, parasails, boomeramg, euclid 97616d9e3a6SLisandro Dalcin - Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX 97716d9e3a6SLisandro Dalcin preconditioner 97816d9e3a6SLisandro Dalcin 97916d9e3a6SLisandro Dalcin Level: intermediate 98016d9e3a6SLisandro Dalcin 98116d9e3a6SLisandro Dalcin Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()), 98216d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 98316d9e3a6SLisandro Dalcin or with PetscOptionsSetValue(), there are no functions to set them) 98416d9e3a6SLisandro Dalcin 98516d9e3a6SLisandro Dalcin The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations 9860f1074feSSatish Balay (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if 9870f1074feSSatish Balay -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner 9880f1074feSSatish Balay (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of 9898f87f92bSBarry Smith iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations 9900f1074feSSatish Balay and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10 9910f1074feSSatish Balay then AT MOST twenty V-cycles of boomeramg will be called. 99216d9e3a6SLisandro Dalcin 9930f1074feSSatish Balay Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation 9940f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 9950f1074feSSatish Balay Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi. 99616d9e3a6SLisandro Dalcin If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly 99716d9e3a6SLisandro Dalcin and use -ksp_max_it to control the number of V-cycles. 99816d9e3a6SLisandro Dalcin (see the PETSc FAQ.html at the PETSc website under the Documentation tab). 99916d9e3a6SLisandro Dalcin 100016d9e3a6SLisandro Dalcin 2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option 100116d9e3a6SLisandro Dalcin -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L. 100216d9e3a6SLisandro Dalcin 10039e5bc791SBarry Smith See PCPFMG for access to the hypre Struct PFMG solver 10049e5bc791SBarry Smith 100516d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 10069e5bc791SBarry Smith PCHYPRESetType(), PCPFMG 100716d9e3a6SLisandro Dalcin 100816d9e3a6SLisandro Dalcin M*/ 100916d9e3a6SLisandro Dalcin 101016d9e3a6SLisandro Dalcin EXTERN_C_BEGIN 101116d9e3a6SLisandro Dalcin #undef __FUNCT__ 101216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE" 10137087cfbeSBarry Smith PetscErrorCode PCCreate_HYPRE(PC pc) 101416d9e3a6SLisandro Dalcin { 101516d9e3a6SLisandro Dalcin PC_HYPRE *jac; 101616d9e3a6SLisandro Dalcin PetscErrorCode ierr; 101716d9e3a6SLisandro Dalcin 101816d9e3a6SLisandro Dalcin PetscFunctionBegin; 101938f2d2fdSLisandro Dalcin ierr = PetscNewLog(pc,PC_HYPRE,&jac);CHKERRQ(ierr); 102016d9e3a6SLisandro Dalcin pc->data = jac; 102116d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 102216d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 102316d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 102416d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 102516d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 102616d9e3a6SLisandro Dalcin jac->hypre_type = PETSC_NULL; 102716d9e3a6SLisandro Dalcin /* duplicate communicator for hypre */ 10287adad957SLisandro Dalcin ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(jac->comm_hypre));CHKERRQ(ierr); 102916d9e3a6SLisandro Dalcin ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPRESetType_C","PCHYPRESetType_HYPRE",PCHYPRESetType_HYPRE);CHKERRQ(ierr); 103016d9e3a6SLisandro Dalcin ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPREGetType_C","PCHYPREGetType_HYPRE",PCHYPREGetType_HYPRE);CHKERRQ(ierr); 103116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 103216d9e3a6SLisandro Dalcin } 103316d9e3a6SLisandro Dalcin EXTERN_C_END 1034ebc551c0SBarry Smith 1035f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/ 1036f91d8e95SBarry Smith 1037b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */ 1038b45d2f2cSJed Brown #include <petsc-private/matimpl.h> 1039ebc551c0SBarry Smith 1040ebc551c0SBarry Smith typedef struct { 104168326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 1042f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 10439e5bc791SBarry Smith 10449e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 10454ddd07fcSJed Brown PetscInt its; 10469e5bc791SBarry Smith double tol; 10474ddd07fcSJed Brown PetscInt relax_type; 10484ddd07fcSJed Brown PetscInt rap_type; 10494ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 10504ddd07fcSJed Brown PetscInt max_levels; 1051ebc551c0SBarry Smith } PC_PFMG; 1052ebc551c0SBarry Smith 1053ebc551c0SBarry Smith #undef __FUNCT__ 1054ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG" 1055ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc) 1056ebc551c0SBarry Smith { 1057ebc551c0SBarry Smith PetscErrorCode ierr; 1058f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1059ebc551c0SBarry Smith 1060ebc551c0SBarry Smith PetscFunctionBegin; 106130e6f737SJed Brown if (ex->hsolver) {PetscStackCallHypre(0,HYPRE_StructPFMGDestroy,(ex->hsolver));} 1062f91d8e95SBarry Smith ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr); 1063c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 1064ebc551c0SBarry Smith PetscFunctionReturn(0); 1065ebc551c0SBarry Smith } 1066ebc551c0SBarry Smith 10679e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"}; 10689e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"}; 10699e5bc791SBarry Smith 1070ebc551c0SBarry Smith #undef __FUNCT__ 1071ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG" 1072ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer) 1073ebc551c0SBarry Smith { 1074ebc551c0SBarry Smith PetscErrorCode ierr; 1075ace3abfcSBarry Smith PetscBool iascii; 1076f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1077ebc551c0SBarry Smith 1078ebc551c0SBarry Smith PetscFunctionBegin; 1079251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 10809e5bc791SBarry Smith if (iascii) { 10819e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG preconditioning\n");CHKERRQ(ierr); 10829e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr); 10839e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr); 10849e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr); 10859e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr); 10869e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr); 10873b46a515SGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr); 10889e5bc791SBarry Smith } 1089ebc551c0SBarry Smith PetscFunctionReturn(0); 1090ebc551c0SBarry Smith } 1091ebc551c0SBarry Smith 10929e5bc791SBarry Smith 1093ebc551c0SBarry Smith #undef __FUNCT__ 1094ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG" 1095ebc551c0SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PC pc) 1096ebc551c0SBarry Smith { 1097ebc551c0SBarry Smith PetscErrorCode ierr; 1098f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1099ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1100ebc551c0SBarry Smith 1101ebc551c0SBarry Smith PetscFunctionBegin; 1102ebc551c0SBarry Smith ierr = PetscOptionsHead("PFMG options");CHKERRQ(ierr); 1103acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 110468326731SBarry Smith if (flg) { 1105a0324ebeSBarry Smith int level=3; 110630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level)); 110768326731SBarry Smith } 11089e5bc791SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,PETSC_NULL);CHKERRQ(ierr); 110930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its)); 11109e5bc791SBarry 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,PETSC_NULL);CHKERRQ(ierr); 111130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax)); 11129e5bc791SBarry 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,PETSC_NULL);CHKERRQ(ierr); 111330e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax)); 11149e5bc791SBarry Smith 11153b46a515SGlenn Hammond ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,PETSC_NULL);CHKERRQ(ierr); 111630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels)); 11173b46a515SGlenn Hammond 11189e5bc791SBarry Smith ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,PETSC_NULL);CHKERRQ(ierr); 111930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol)); 11209e5bc791SBarry Smith ierr = PetscOptionsEList("-pc_pfmg_relax_type","Relax type for the up and down cycles","HYPRE_StructPFMGSetRelaxType",PFMGRelaxType,4,PFMGRelaxType[ex->relax_type],&ex->relax_type,PETSC_NULL);CHKERRQ(ierr); 112130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type)); 11229e5bc791SBarry Smith ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,2,PFMGRAPType[ex->rap_type],&ex->rap_type,PETSC_NULL);CHKERRQ(ierr); 112330e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type)); 1124ebc551c0SBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 1125ebc551c0SBarry Smith PetscFunctionReturn(0); 1126ebc551c0SBarry Smith } 1127ebc551c0SBarry Smith 1128f91d8e95SBarry Smith #undef __FUNCT__ 1129f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG" 1130f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y) 1131f91d8e95SBarry Smith { 1132f91d8e95SBarry Smith PetscErrorCode ierr; 1133f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1134f91d8e95SBarry Smith PetscScalar *xx,*yy; 11354ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 113668326731SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 1137f91d8e95SBarry Smith 1138f91d8e95SBarry Smith PetscFunctionBegin; 1139aa219208SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1140f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 1141f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 1142f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 1143f91d8e95SBarry Smith 1144f91d8e95SBarry Smith /* copy x values over to hypre */ 114530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructVectorSetConstantValues,(mx->hb,0.0)); 1146f91d8e95SBarry Smith ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 114730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructVectorSetBoxValues,(mx->hb,ilower,iupper,xx)); 1148f91d8e95SBarry Smith ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 114930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructVectorAssemble,(mx->hb)); 115030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx)); 1151f91d8e95SBarry Smith 1152f91d8e95SBarry Smith /* copy solution values back to PETSc */ 1153f91d8e95SBarry Smith ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 115430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructVectorGetBoxValues,(mx->hx,ilower,iupper,yy)); 1155f91d8e95SBarry Smith ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1156f91d8e95SBarry Smith PetscFunctionReturn(0); 1157f91d8e95SBarry Smith } 1158f91d8e95SBarry Smith 11599e5bc791SBarry Smith #undef __FUNCT__ 11609e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG" 1161ace3abfcSBarry 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) 11629e5bc791SBarry Smith { 11639e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG*)pc->data; 11649e5bc791SBarry Smith PetscErrorCode ierr; 11654ddd07fcSJed Brown PetscInt oits; 11669e5bc791SBarry Smith 11679e5bc791SBarry Smith PetscFunctionBegin; 116830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its)); 116930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(jac->hsolver,rtol)); 11709e5bc791SBarry Smith 11719e5bc791SBarry Smith ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr); 117230e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits)); 11739e5bc791SBarry Smith *outits = oits; 11749e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 11759e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 117630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol)); 117730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its)); 11789e5bc791SBarry Smith PetscFunctionReturn(0); 11799e5bc791SBarry Smith } 11809e5bc791SBarry Smith 11819e5bc791SBarry Smith 11823a32d3dbSGlenn Hammond #undef __FUNCT__ 11833a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG" 11843a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc) 11853a32d3dbSGlenn Hammond { 11863a32d3dbSGlenn Hammond PetscErrorCode ierr; 11873a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG*) pc->data; 11883a32d3dbSGlenn Hammond Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data); 1189ace3abfcSBarry Smith PetscBool flg; 11903a32d3dbSGlenn Hammond 11913a32d3dbSGlenn Hammond PetscFunctionBegin; 1192251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr); 1193e7e72b3dSBarry Smith if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner"); 11943a32d3dbSGlenn Hammond 11953a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 11963a32d3dbSGlenn Hammond if (ex->hsolver) { 119730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGDestroy,(ex->hsolver)); 11983a32d3dbSGlenn Hammond } 119930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver)); 12003a32d3dbSGlenn Hammond ierr = PCSetFromOptions_PFMG(pc);CHKERRQ(ierr); 120130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx)); 120230e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGSetZeroGuess,(ex->hsolver)); 12033a32d3dbSGlenn Hammond PetscFunctionReturn(0); 12043a32d3dbSGlenn Hammond } 12053a32d3dbSGlenn Hammond 1206ebc551c0SBarry Smith 1207ebc551c0SBarry Smith /*MC 1208ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 1209ebc551c0SBarry Smith 1210ebc551c0SBarry Smith Level: advanced 1211ebc551c0SBarry Smith 12129e5bc791SBarry Smith Options Database: 12139e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner 12149e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid 12159e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid 12169e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG 12179e5bc791SBarry 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 12189e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 1219f91d8e95SBarry Smith 12209e5bc791SBarry Smith Notes: This is for CELL-centered descretizations 12219e5bc791SBarry Smith 12228e395302SJed Brown This must be used with the MATHYPRESTRUCT matrix type. 1223aa219208SBarry Smith This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA. 12249e5bc791SBarry Smith 12259e5bc791SBarry Smith .seealso: PCMG, MATHYPRESTRUCT 1226ebc551c0SBarry Smith M*/ 1227ebc551c0SBarry Smith 1228ebc551c0SBarry Smith EXTERN_C_BEGIN 1229ebc551c0SBarry Smith #undef __FUNCT__ 1230ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG" 12317087cfbeSBarry Smith PetscErrorCode PCCreate_PFMG(PC pc) 1232ebc551c0SBarry Smith { 1233ebc551c0SBarry Smith PetscErrorCode ierr; 1234ebc551c0SBarry Smith PC_PFMG *ex; 1235ebc551c0SBarry Smith 1236ebc551c0SBarry Smith PetscFunctionBegin; 1237ebc551c0SBarry Smith ierr = PetscNew(PC_PFMG,&ex);CHKERRQ(ierr);\ 123868326731SBarry Smith pc->data = ex; 1239ebc551c0SBarry Smith 12409e5bc791SBarry Smith ex->its = 1; 12419e5bc791SBarry Smith ex->tol = 1.e-8; 12429e5bc791SBarry Smith ex->relax_type = 1; 12439e5bc791SBarry Smith ex->rap_type = 0; 12449e5bc791SBarry Smith ex->num_pre_relax = 1; 12459e5bc791SBarry Smith ex->num_post_relax = 1; 12463b46a515SGlenn Hammond ex->max_levels = 0; 12479e5bc791SBarry Smith 1248ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 1249ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 1250ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 1251f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 12529e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 125368326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 1254f91d8e95SBarry Smith ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(ex->hcomm));CHKERRQ(ierr); 125530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver)); 1256ebc551c0SBarry Smith PetscFunctionReturn(0); 1257ebc551c0SBarry Smith } 1258ebc551c0SBarry Smith EXTERN_C_END 1259d851a50bSGlenn Hammond 1260325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/ 1261325fc9f4SBarry Smith 1262d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 1263d851a50bSGlenn Hammond typedef struct { 1264d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 1265d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 1266d851a50bSGlenn Hammond 1267d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 12684ddd07fcSJed Brown PetscInt its; 1269d851a50bSGlenn Hammond double tol; 12704ddd07fcSJed Brown PetscInt relax_type; 12714ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 1272d851a50bSGlenn Hammond } PC_SysPFMG; 1273d851a50bSGlenn Hammond 1274d851a50bSGlenn Hammond #undef __FUNCT__ 1275d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG" 1276d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc) 1277d851a50bSGlenn Hammond { 1278d851a50bSGlenn Hammond PetscErrorCode ierr; 1279d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1280d851a50bSGlenn Hammond 1281d851a50bSGlenn Hammond PetscFunctionBegin; 128230e6f737SJed Brown if (ex->ss_solver) {PetscStackCallHypre(0,HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));} 1283d851a50bSGlenn Hammond ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr); 1284c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 1285d851a50bSGlenn Hammond PetscFunctionReturn(0); 1286d851a50bSGlenn Hammond } 1287d851a50bSGlenn Hammond 1288d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"}; 1289d851a50bSGlenn Hammond 1290d851a50bSGlenn Hammond #undef __FUNCT__ 1291d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG" 1292d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer) 1293d851a50bSGlenn Hammond { 1294d851a50bSGlenn Hammond PetscErrorCode ierr; 1295ace3abfcSBarry Smith PetscBool iascii; 1296d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1297d851a50bSGlenn Hammond 1298d851a50bSGlenn Hammond PetscFunctionBegin; 1299251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1300d851a50bSGlenn Hammond if (iascii) { 1301d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr); 1302d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr); 1303d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr); 1304d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr); 1305d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr); 1306d851a50bSGlenn Hammond } 1307d851a50bSGlenn Hammond PetscFunctionReturn(0); 1308d851a50bSGlenn Hammond } 1309d851a50bSGlenn Hammond 1310d851a50bSGlenn Hammond 1311d851a50bSGlenn Hammond #undef __FUNCT__ 1312d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG" 1313d851a50bSGlenn Hammond PetscErrorCode PCSetFromOptions_SysPFMG(PC pc) 1314d851a50bSGlenn Hammond { 1315d851a50bSGlenn Hammond PetscErrorCode ierr; 1316d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1317ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1318d851a50bSGlenn Hammond 1319d851a50bSGlenn Hammond PetscFunctionBegin; 1320d851a50bSGlenn Hammond ierr = PetscOptionsHead("SysPFMG options");CHKERRQ(ierr); 1321acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 1322d851a50bSGlenn Hammond if (flg) { 1323d851a50bSGlenn Hammond int level=3; 132430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level)); 1325d851a50bSGlenn Hammond } 1326d851a50bSGlenn Hammond ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,PETSC_NULL);CHKERRQ(ierr); 132730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its)); 1328d851a50bSGlenn Hammond ierr = PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,PETSC_NULL);CHKERRQ(ierr); 132930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax)); 1330d851a50bSGlenn Hammond ierr = PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,PETSC_NULL);CHKERRQ(ierr); 133130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax)); 1332d851a50bSGlenn Hammond 1333d851a50bSGlenn Hammond ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,PETSC_NULL);CHKERRQ(ierr); 133430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol)); 1335d851a50bSGlenn Hammond 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,PETSC_NULL);CHKERRQ(ierr); 133630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type)); 1337d851a50bSGlenn Hammond ierr = PetscOptionsTail();CHKERRQ(ierr); 1338d851a50bSGlenn Hammond PetscFunctionReturn(0); 1339d851a50bSGlenn Hammond } 1340d851a50bSGlenn Hammond 1341d851a50bSGlenn Hammond #undef __FUNCT__ 1342d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG" 1343d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y) 1344d851a50bSGlenn Hammond { 1345d851a50bSGlenn Hammond PetscErrorCode ierr; 1346d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1347d851a50bSGlenn Hammond PetscScalar *xx,*yy; 13484ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 1349d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)(pc->pmat->data); 13504ddd07fcSJed Brown PetscInt ordering= mx->dofs_order; 13514ddd07fcSJed Brown PetscInt nvars= mx->nvars; 13524ddd07fcSJed Brown PetscInt part= 0; 13534ddd07fcSJed Brown PetscInt size; 13544ddd07fcSJed Brown PetscInt i; 1355d851a50bSGlenn Hammond 1356d851a50bSGlenn Hammond PetscFunctionBegin; 1357aa219208SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1358d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 1359d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 1360d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 1361d851a50bSGlenn Hammond 1362d851a50bSGlenn Hammond size= 1; 1363d851a50bSGlenn Hammond for (i= 0; i< 3; i++) { 1364d851a50bSGlenn Hammond size*= (iupper[i]-ilower[i]+1); 1365d851a50bSGlenn Hammond } 1366d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 1367d851a50bSGlenn Hammond if (ordering) { 136830e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0)); 1369d851a50bSGlenn Hammond ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 1370d851a50bSGlenn Hammond for (i= 0; i< nvars; i++) { 137130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,ilower,iupper,i,xx+(size*i))); 1372d851a50bSGlenn Hammond } 1373d851a50bSGlenn Hammond ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 137430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructVectorAssemble,(mx->ss_b)); 137530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x)); 137630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1377d851a50bSGlenn Hammond 1378d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 1379d851a50bSGlenn Hammond ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 1380d851a50bSGlenn Hammond for (i= 0; i< nvars; i++) { 138130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,ilower,iupper,i,yy+(size*i))); 1382d851a50bSGlenn Hammond } 1383d851a50bSGlenn Hammond ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1384a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 1385d851a50bSGlenn Hammond PetscScalar *z; 13864ddd07fcSJed Brown PetscInt j, k; 1387d851a50bSGlenn Hammond 1388d851a50bSGlenn Hammond ierr = PetscMalloc(nvars*size*sizeof(PetscScalar),&z);CHKERRQ(ierr); 138930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0)); 1390d851a50bSGlenn Hammond ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 1391d851a50bSGlenn Hammond 1392d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 1393d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 1394d851a50bSGlenn Hammond k= i*nvars; 1395d851a50bSGlenn Hammond for (j= 0; j< nvars; j++) { 1396d851a50bSGlenn Hammond z[j*size+i]= xx[k+j]; 1397d851a50bSGlenn Hammond } 1398d851a50bSGlenn Hammond } 1399d851a50bSGlenn Hammond for (i= 0; i< nvars; i++) { 140030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,ilower,iupper,i,z+(size*i))); 1401d851a50bSGlenn Hammond } 1402d851a50bSGlenn Hammond ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 140330e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructVectorAssemble,(mx->ss_b)); 140430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1405d851a50bSGlenn Hammond 1406d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 1407d851a50bSGlenn Hammond ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 1408d851a50bSGlenn Hammond for (i= 0; i< nvars; i++) { 140930e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,ilower,iupper,i,z+(size*i))); 1410d851a50bSGlenn Hammond } 1411d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 1412d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 1413d851a50bSGlenn Hammond k= i*nvars; 1414d851a50bSGlenn Hammond for (j= 0; j< nvars; j++) { 1415d851a50bSGlenn Hammond yy[k+j]= z[j*size+i]; 1416d851a50bSGlenn Hammond } 1417d851a50bSGlenn Hammond } 1418d851a50bSGlenn Hammond ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1419d851a50bSGlenn Hammond ierr = PetscFree(z);CHKERRQ(ierr); 1420d851a50bSGlenn Hammond } 1421d851a50bSGlenn Hammond PetscFunctionReturn(0); 1422d851a50bSGlenn Hammond } 1423d851a50bSGlenn Hammond 1424d851a50bSGlenn Hammond #undef __FUNCT__ 1425d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG" 1426ace3abfcSBarry 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) 1427d851a50bSGlenn Hammond { 1428d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG*)pc->data; 1429d851a50bSGlenn Hammond PetscErrorCode ierr; 14304ddd07fcSJed Brown PetscInt oits; 1431d851a50bSGlenn Hammond 1432d851a50bSGlenn Hammond PetscFunctionBegin; 143330e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its)); 143430e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol)); 1435d851a50bSGlenn Hammond ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr); 143630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits)); 1437d851a50bSGlenn Hammond *outits = oits; 1438d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 1439d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 144030e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol)); 144130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its)); 1442d851a50bSGlenn Hammond PetscFunctionReturn(0); 1443d851a50bSGlenn Hammond } 1444d851a50bSGlenn Hammond 1445d851a50bSGlenn Hammond 1446d851a50bSGlenn Hammond #undef __FUNCT__ 1447d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG" 1448d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc) 1449d851a50bSGlenn Hammond { 1450d851a50bSGlenn Hammond PetscErrorCode ierr; 1451d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1452d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)(pc->pmat->data); 1453ace3abfcSBarry Smith PetscBool flg; 1454d851a50bSGlenn Hammond 1455d851a50bSGlenn Hammond PetscFunctionBegin; 1456251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr); 1457e7e72b3dSBarry Smith if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner"); 1458d851a50bSGlenn Hammond 1459d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 1460d851a50bSGlenn Hammond if (ex->ss_solver) { 146130e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGDestroy,(ex->ss_solver)); 1462d851a50bSGlenn Hammond } 146330e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver)); 1464d851a50bSGlenn Hammond ierr = PCSetFromOptions_SysPFMG(pc);CHKERRQ(ierr); 146530e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver)); 146630e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1467d851a50bSGlenn Hammond PetscFunctionReturn(0); 1468d851a50bSGlenn Hammond } 1469d851a50bSGlenn Hammond 1470d851a50bSGlenn Hammond 1471d851a50bSGlenn Hammond /*MC 1472d851a50bSGlenn Hammond PCSysPFMG - the hypre SysPFMG multigrid solver 1473d851a50bSGlenn Hammond 1474d851a50bSGlenn Hammond Level: advanced 1475d851a50bSGlenn Hammond 1476d851a50bSGlenn Hammond Options Database: 1477d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner 1478d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid 1479d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid 1480d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG 1481d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel 1482d851a50bSGlenn Hammond 1483d851a50bSGlenn Hammond Notes: This is for CELL-centered descretizations 1484d851a50bSGlenn Hammond 1485f6680f47SSatish Balay This must be used with the MATHYPRESSTRUCT matrix type. 1486aa219208SBarry Smith This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA. 1487d851a50bSGlenn Hammond Also, only cell-centered variables. 1488d851a50bSGlenn Hammond 1489d851a50bSGlenn Hammond .seealso: PCMG, MATHYPRESSTRUCT 1490d851a50bSGlenn Hammond M*/ 1491d851a50bSGlenn Hammond 1492d851a50bSGlenn Hammond EXTERN_C_BEGIN 1493d851a50bSGlenn Hammond #undef __FUNCT__ 1494d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG" 14957087cfbeSBarry Smith PetscErrorCode PCCreate_SysPFMG(PC pc) 1496d851a50bSGlenn Hammond { 1497d851a50bSGlenn Hammond PetscErrorCode ierr; 1498d851a50bSGlenn Hammond PC_SysPFMG *ex; 1499d851a50bSGlenn Hammond 1500d851a50bSGlenn Hammond PetscFunctionBegin; 1501d851a50bSGlenn Hammond ierr = PetscNew(PC_SysPFMG,&ex);CHKERRQ(ierr);\ 1502d851a50bSGlenn Hammond pc->data = ex; 1503d851a50bSGlenn Hammond 1504d851a50bSGlenn Hammond ex->its = 1; 1505d851a50bSGlenn Hammond ex->tol = 1.e-8; 1506d851a50bSGlenn Hammond ex->relax_type = 1; 1507d851a50bSGlenn Hammond ex->num_pre_relax = 1; 1508d851a50bSGlenn Hammond ex->num_post_relax = 1; 1509d851a50bSGlenn Hammond 1510d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 1511d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 1512d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 1513d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 1514d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 1515d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 1516d851a50bSGlenn Hammond ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(ex->hcomm));CHKERRQ(ierr); 151730e6f737SJed Brown PetscStackCallHypre(0,HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver)); 1518d851a50bSGlenn Hammond PetscFunctionReturn(0); 1519d851a50bSGlenn Hammond } 1520d851a50bSGlenn Hammond EXTERN_C_END 1521