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> 10*4cb006feSStefano Zampini #include <_hypre_parcsr_ls.h> 1116d9e3a6SLisandro Dalcin 12dff31646SBarry Smith static PetscBool cite = PETSC_FALSE; 131f817a21SBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n title = {{\\sl hypre}: High Performance Preconditioners},\n organization = {Lawrence Livermore National Laboratory},\n note = {\\url{http://www.llnl.gov/CASC/hypre/}}\n}\n"; 141f817a21SBarry Smith 1516d9e3a6SLisandro Dalcin /* 1616d9e3a6SLisandro Dalcin Private context (data structure) for the preconditioner. 1716d9e3a6SLisandro Dalcin */ 1816d9e3a6SLisandro Dalcin typedef struct { 1916d9e3a6SLisandro Dalcin HYPRE_Solver hsolver; 2016d9e3a6SLisandro Dalcin HYPRE_IJMatrix ij; 2116d9e3a6SLisandro Dalcin HYPRE_IJVector b,x; 2216d9e3a6SLisandro Dalcin 234ddd07fcSJed Brown HYPRE_Int (*destroy)(HYPRE_Solver); 244ddd07fcSJed Brown HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 254ddd07fcSJed Brown HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 2616d9e3a6SLisandro Dalcin 2716d9e3a6SLisandro Dalcin MPI_Comm comm_hypre; 2816d9e3a6SLisandro Dalcin char *hypre_type; 2916d9e3a6SLisandro Dalcin 3016d9e3a6SLisandro Dalcin /* options for Pilut and BoomerAMG*/ 314ddd07fcSJed Brown PetscInt maxiter; 3216d9e3a6SLisandro Dalcin double tol; 3316d9e3a6SLisandro Dalcin 3416d9e3a6SLisandro Dalcin /* options for Pilut */ 354ddd07fcSJed Brown PetscInt factorrowsize; 3616d9e3a6SLisandro Dalcin 3716d9e3a6SLisandro Dalcin /* options for ParaSails */ 384ddd07fcSJed Brown PetscInt nlevels; 3916d9e3a6SLisandro Dalcin double threshhold; 4016d9e3a6SLisandro Dalcin double filter; 414ddd07fcSJed Brown PetscInt sym; 4216d9e3a6SLisandro Dalcin double loadbal; 434ddd07fcSJed Brown PetscInt logging; 444ddd07fcSJed Brown PetscInt ruse; 454ddd07fcSJed Brown PetscInt symt; 4616d9e3a6SLisandro Dalcin 4716d9e3a6SLisandro Dalcin /* options for Euclid */ 48ace3abfcSBarry Smith PetscBool bjilu; 494ddd07fcSJed Brown PetscInt levels; 5016d9e3a6SLisandro Dalcin 5116d9e3a6SLisandro Dalcin /* options for Euclid and BoomerAMG */ 52ace3abfcSBarry Smith PetscBool printstatistics; 5316d9e3a6SLisandro Dalcin 5416d9e3a6SLisandro Dalcin /* options for BoomerAMG */ 554ddd07fcSJed Brown PetscInt cycletype; 564ddd07fcSJed Brown PetscInt maxlevels; 5716d9e3a6SLisandro Dalcin double strongthreshold; 5816d9e3a6SLisandro Dalcin double maxrowsum; 594ddd07fcSJed Brown PetscInt gridsweeps[3]; 604ddd07fcSJed Brown PetscInt coarsentype; 614ddd07fcSJed Brown PetscInt measuretype; 624ddd07fcSJed Brown PetscInt relaxtype[3]; 6316d9e3a6SLisandro Dalcin double relaxweight; 6416d9e3a6SLisandro Dalcin double outerrelaxweight; 654ddd07fcSJed Brown PetscInt relaxorder; 6616d9e3a6SLisandro Dalcin double truncfactor; 67ace3abfcSBarry Smith PetscBool applyrichardson; 684ddd07fcSJed Brown PetscInt pmax; 694ddd07fcSJed Brown PetscInt interptype; 704ddd07fcSJed Brown PetscInt agg_nl; 714ddd07fcSJed Brown PetscInt agg_num_paths; 724ddd07fcSJed Brown PetscInt nodal_coarsen; 73ace3abfcSBarry Smith PetscBool nodal_relax; 744ddd07fcSJed Brown PetscInt nodal_relax_levels; 75*4cb006feSStefano Zampini 76*4cb006feSStefano Zampini /* options for AMS */ 77*4cb006feSStefano Zampini PetscInt ams_print; 78*4cb006feSStefano Zampini PetscInt ams_max_iter; 79*4cb006feSStefano Zampini PetscInt ams_cycle_type; 80*4cb006feSStefano Zampini PetscReal ams_tol; 81*4cb006feSStefano Zampini PetscInt ams_relax_type; 82*4cb006feSStefano Zampini PetscInt ams_relax_times; 83*4cb006feSStefano Zampini PetscReal ams_relax_weight; 84*4cb006feSStefano Zampini PetscReal ams_omega; 85*4cb006feSStefano Zampini PetscInt ams_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson */ 86*4cb006feSStefano Zampini PetscReal ams_amg_alpha_theta; /* AMG strength for vector Poisson */ 87*4cb006feSStefano Zampini PetscInt ams_amg_beta_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson */ 88*4cb006feSStefano Zampini PetscReal ams_amg_beta_theta; /* AMG strength for scalar Poisson */ 89*4cb006feSStefano Zampini 90*4cb006feSStefano Zampini /* additional data */ 91*4cb006feSStefano Zampini HYPRE_IJVector coords[3]; 92*4cb006feSStefano Zampini HYPRE_IJVector constants[3]; 93*4cb006feSStefano Zampini HYPRE_IJMatrix G; 94*4cb006feSStefano Zampini HYPRE_IJMatrix alpha_Poisson; 95*4cb006feSStefano Zampini HYPRE_IJMatrix beta_Poisson; 96*4cb006feSStefano Zampini PetscBool ams_beta_is_zero; 9716d9e3a6SLisandro Dalcin } PC_HYPRE; 9816d9e3a6SLisandro Dalcin 99d2128fa2SBarry Smith #undef __FUNCT__ 100d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver" 101d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver) 102d2128fa2SBarry Smith { 103d2128fa2SBarry Smith PC_HYPRE *jac = (PC_HYPRE*)pc->data; 104d2128fa2SBarry Smith 105d2128fa2SBarry Smith PetscFunctionBegin; 106d2128fa2SBarry Smith *hsolver = jac->hsolver; 107d2128fa2SBarry Smith PetscFunctionReturn(0); 108d2128fa2SBarry Smith } 10916d9e3a6SLisandro Dalcin 11016d9e3a6SLisandro Dalcin #undef __FUNCT__ 11116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE" 11216d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc) 11316d9e3a6SLisandro Dalcin { 11416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 11516d9e3a6SLisandro Dalcin PetscErrorCode ierr; 11616d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 11716d9e3a6SLisandro Dalcin HYPRE_ParVector bv,xv; 11816d9e3a6SLisandro Dalcin PetscInt bs; 11916d9e3a6SLisandro Dalcin 12016d9e3a6SLisandro Dalcin PetscFunctionBegin; 12116d9e3a6SLisandro Dalcin if (!jac->hypre_type) { 12202a17cd4SBarry Smith ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr); 12316d9e3a6SLisandro Dalcin } 1245f5c5b43SBarry Smith 1255f5c5b43SBarry Smith if (pc->setupcalled) { 1265f5c5b43SBarry Smith /* always destroy the old matrix and create a new memory; 1275f5c5b43SBarry Smith hope this does not churn the memory too much. The problem 1285f5c5b43SBarry Smith is I do not know if it is possible to put the matrix back to 1295f5c5b43SBarry Smith its initial state so that we can directly copy the values 1305f5c5b43SBarry Smith the second time through. */ 131fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij)); 1325f5c5b43SBarry Smith jac->ij = 0; 13316d9e3a6SLisandro Dalcin } 1345f5c5b43SBarry Smith 13516d9e3a6SLisandro Dalcin if (!jac->ij) { /* create the matrix the first time through */ 13616d9e3a6SLisandro Dalcin ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr); 13716d9e3a6SLisandro Dalcin } 13816d9e3a6SLisandro Dalcin if (!jac->b) { /* create the vectors the first time through */ 13916d9e3a6SLisandro Dalcin Vec x,b; 14016d9e3a6SLisandro Dalcin ierr = MatGetVecs(pc->pmat,&x,&b);CHKERRQ(ierr); 14116d9e3a6SLisandro Dalcin ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr); 14216d9e3a6SLisandro Dalcin ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr); 1436bf464f9SBarry Smith ierr = VecDestroy(&x);CHKERRQ(ierr); 1446bf464f9SBarry Smith ierr = VecDestroy(&b);CHKERRQ(ierr); 14516d9e3a6SLisandro Dalcin } 1465f5c5b43SBarry Smith 14716d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 14816d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 14916d9e3a6SLisandro Dalcin ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 1502fa5cd67SKarl Rupp if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs)); 151*4cb006feSStefano Zampini } 152*4cb006feSStefano Zampini /* special case for AMS */ 153*4cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 154*4cb006feSStefano Zampini if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either coordinate vectors via PCSetCoordinates() or edge constant vectors via PCHYPRESetEdgeConstantVectors()"); 155*4cb006feSStefano Zampini if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient"); 156*4cb006feSStefano Zampini } 15716d9e3a6SLisandro Dalcin ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr); 158fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 159fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv)); 160fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv)); 161fd3f9acdSBarry Smith PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr);); 16216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 16316d9e3a6SLisandro Dalcin } 16416d9e3a6SLisandro Dalcin 16516d9e3a6SLisandro Dalcin /* 16616d9e3a6SLisandro Dalcin Replaces the address where the HYPRE vector points to its data with the address of 16716d9e3a6SLisandro Dalcin PETSc's data. Saves the old address so it can be reset when we are finished with it. 16816d9e3a6SLisandro Dalcin Allows use to get the data into a HYPRE vector without the cost of memcopies 16916d9e3a6SLisandro Dalcin */ 17016d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \ 17116d9e3a6SLisandro Dalcin hypre_ParVector *par_vector = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \ 17216d9e3a6SLisandro Dalcin hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); \ 17316d9e3a6SLisandro Dalcin savedvalue = local_vector->data; \ 1740ad7597dSKarl Rupp local_vector->data = newvalue; \ 1750ad7597dSKarl Rupp } 17616d9e3a6SLisandro Dalcin 17716d9e3a6SLisandro Dalcin #undef __FUNCT__ 17816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE" 17916d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x) 18016d9e3a6SLisandro Dalcin { 18116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 18216d9e3a6SLisandro Dalcin PetscErrorCode ierr; 18316d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 18416d9e3a6SLisandro Dalcin PetscScalar *bv,*xv; 18516d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 18616d9e3a6SLisandro Dalcin PetscScalar *sbv,*sxv; 1874ddd07fcSJed Brown PetscInt hierr; 18816d9e3a6SLisandro Dalcin 18916d9e3a6SLisandro Dalcin PetscFunctionBegin; 190dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 19116d9e3a6SLisandro Dalcin if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);} 19216d9e3a6SLisandro Dalcin ierr = VecGetArray(b,&bv);CHKERRQ(ierr); 19316d9e3a6SLisandro Dalcin ierr = VecGetArray(x,&xv);CHKERRQ(ierr); 19416d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,bv,sbv); 19516d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,xv,sxv); 19616d9e3a6SLisandro Dalcin 197fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 198fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv)); 199fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv)); 200fd3f9acdSBarry Smith PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv); 20165e19b50SBarry Smith if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr); 202fd3f9acdSBarry Smith if (hierr) hypre__global_error = 0;); 20316d9e3a6SLisandro Dalcin 20416d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,sbv,bv); 20516d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,sxv,xv); 20616d9e3a6SLisandro Dalcin ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr); 20716d9e3a6SLisandro Dalcin ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr); 20816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 20916d9e3a6SLisandro Dalcin } 21016d9e3a6SLisandro Dalcin 21116d9e3a6SLisandro Dalcin #undef __FUNCT__ 21216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE" 21316d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc) 21416d9e3a6SLisandro Dalcin { 21516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 21616d9e3a6SLisandro Dalcin PetscErrorCode ierr; 21716d9e3a6SLisandro Dalcin 21816d9e3a6SLisandro Dalcin PetscFunctionBegin; 219fd3f9acdSBarry Smith if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij)); 220fd3f9acdSBarry Smith if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b)); 221fd3f9acdSBarry Smith if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x)); 222*4cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); 223*4cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); 224*4cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); 225*4cb006feSStefano Zampini if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); 226*4cb006feSStefano Zampini if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); 227*4cb006feSStefano Zampini if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); 228*4cb006feSStefano Zampini if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); 229*4cb006feSStefano Zampini if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); 230*4cb006feSStefano Zampini if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); 231226b0620SJed Brown if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr);); 232503cfb0cSBarry Smith ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr); 23316d9e3a6SLisandro Dalcin if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);} 234c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 23516d9e3a6SLisandro Dalcin 23616d9e3a6SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr); 237bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr); 238bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr); 239*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr); 240*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr); 241*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr); 242*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr); 243*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr); 24416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 24516d9e3a6SLisandro Dalcin } 24616d9e3a6SLisandro Dalcin 24716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 24816d9e3a6SLisandro Dalcin #undef __FUNCT__ 24916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut" 25016d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc) 25116d9e3a6SLisandro Dalcin { 25216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 25316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 254ace3abfcSBarry Smith PetscBool flag; 25516d9e3a6SLisandro Dalcin 25616d9e3a6SLisandro Dalcin PetscFunctionBegin; 25716d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE Pilut Options");CHKERRQ(ierr); 25816d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr); 259fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter)); 26016d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr); 261fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol)); 26216d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr); 263fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize)); 26416d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 26516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 26616d9e3a6SLisandro Dalcin } 26716d9e3a6SLisandro Dalcin 26816d9e3a6SLisandro Dalcin #undef __FUNCT__ 26916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut" 27016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer) 27116d9e3a6SLisandro Dalcin { 27216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 27316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 274ace3abfcSBarry Smith PetscBool iascii; 27516d9e3a6SLisandro Dalcin 27616d9e3a6SLisandro Dalcin PetscFunctionBegin; 277251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 27816d9e3a6SLisandro Dalcin if (iascii) { 27916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut preconditioning\n");CHKERRQ(ierr); 28016d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 28116d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr); 28216d9e3a6SLisandro Dalcin } else { 28316d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr); 28416d9e3a6SLisandro Dalcin } 28516d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 28657622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr); 28716d9e3a6SLisandro Dalcin } else { 28816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr); 28916d9e3a6SLisandro Dalcin } 29016d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 29116d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr); 29216d9e3a6SLisandro Dalcin } else { 29316d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default factor row size \n");CHKERRQ(ierr); 29416d9e3a6SLisandro Dalcin } 29516d9e3a6SLisandro Dalcin } 29616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 29716d9e3a6SLisandro Dalcin } 29816d9e3a6SLisandro Dalcin 29916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 30016d9e3a6SLisandro Dalcin #undef __FUNCT__ 30116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Euclid" 30216d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc) 30316d9e3a6SLisandro Dalcin { 30416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 30516d9e3a6SLisandro Dalcin PetscErrorCode ierr; 306ace3abfcSBarry Smith PetscBool flag; 307390e7148SBarry Smith char *args[8],levels[16]; 308390e7148SBarry Smith PetscInt cnt = 0; 30916d9e3a6SLisandro Dalcin 31016d9e3a6SLisandro Dalcin PetscFunctionBegin; 31116d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE Euclid Options");CHKERRQ(ierr); 31216d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_euclid_levels","Number of levels of fill ILU(k)","None",jac->levels,&jac->levels,&flag);CHKERRQ(ierr); 31316d9e3a6SLisandro Dalcin if (flag) { 314ce94432eSBarry Smith if (jac->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be nonegative",jac->levels); 3158caf3d72SBarry Smith ierr = PetscSNPrintf(levels,sizeof(levels),"%D",jac->levels);CHKERRQ(ierr); 316390e7148SBarry Smith args[cnt++] = (char*)"-level"; args[cnt++] = levels; 31716d9e3a6SLisandro Dalcin } 3180298fd71SBarry Smith ierr = PetscOptionsBool("-pc_hypre_euclid_bj","Use block Jacobi ILU(k)","None",jac->bjilu,&jac->bjilu,NULL);CHKERRQ(ierr); 31916d9e3a6SLisandro Dalcin if (jac->bjilu) { 320390e7148SBarry Smith args[cnt++] =(char*) "-bj"; args[cnt++] = (char*)"1"; 32116d9e3a6SLisandro Dalcin } 32216d9e3a6SLisandro Dalcin 3230298fd71SBarry Smith ierr = PetscOptionsBool("-pc_hypre_euclid_print_statistics","Print statistics","None",jac->printstatistics,&jac->printstatistics,NULL);CHKERRQ(ierr); 32416d9e3a6SLisandro Dalcin if (jac->printstatistics) { 325390e7148SBarry Smith args[cnt++] = (char*)"-eu_stats"; args[cnt++] = (char*)"1"; 326390e7148SBarry Smith args[cnt++] = (char*)"-eu_mem"; args[cnt++] = (char*)"1"; 32716d9e3a6SLisandro Dalcin } 32816d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 329fd3f9acdSBarry Smith if (cnt) PetscStackCallStandard(HYPRE_EuclidSetParams,(jac->hsolver,cnt,args)); 33016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 33116d9e3a6SLisandro Dalcin } 33216d9e3a6SLisandro Dalcin 33316d9e3a6SLisandro Dalcin #undef __FUNCT__ 33416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Euclid" 33516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer) 33616d9e3a6SLisandro Dalcin { 33716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 33816d9e3a6SLisandro Dalcin PetscErrorCode ierr; 339ace3abfcSBarry Smith PetscBool iascii; 34016d9e3a6SLisandro Dalcin 34116d9e3a6SLisandro Dalcin PetscFunctionBegin; 342251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 34316d9e3a6SLisandro Dalcin if (iascii) { 34416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Euclid preconditioning\n");CHKERRQ(ierr); 34516d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Euclid: number of levels %d\n",jac->levels);CHKERRQ(ierr); 34616d9e3a6SLisandro Dalcin if (jac->bjilu) { 34716d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Euclid: Using block Jacobi ILU instead of parallel ILU\n");CHKERRQ(ierr); 34816d9e3a6SLisandro Dalcin } 34916d9e3a6SLisandro Dalcin } 35016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 35116d9e3a6SLisandro Dalcin } 35216d9e3a6SLisandro Dalcin 35316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 35416d9e3a6SLisandro Dalcin 35516d9e3a6SLisandro Dalcin #undef __FUNCT__ 35616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG" 35716d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x) 35816d9e3a6SLisandro Dalcin { 35916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 36016d9e3a6SLisandro Dalcin PetscErrorCode ierr; 36116d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 36216d9e3a6SLisandro Dalcin PetscScalar *bv,*xv; 36316d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 36416d9e3a6SLisandro Dalcin PetscScalar *sbv,*sxv; 3654ddd07fcSJed Brown PetscInt hierr; 36616d9e3a6SLisandro Dalcin 36716d9e3a6SLisandro Dalcin PetscFunctionBegin; 368dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 36916d9e3a6SLisandro Dalcin ierr = VecSet(x,0.0);CHKERRQ(ierr); 37016d9e3a6SLisandro Dalcin ierr = VecGetArray(b,&bv);CHKERRQ(ierr); 37116d9e3a6SLisandro Dalcin ierr = VecGetArray(x,&xv);CHKERRQ(ierr); 37216d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,bv,sbv); 37316d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,xv,sxv); 37416d9e3a6SLisandro Dalcin 375fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 376fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv)); 377fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv)); 37816d9e3a6SLisandro Dalcin 37916d9e3a6SLisandro Dalcin hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv); 38016d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 381e32f2f54SBarry Smith if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr); 38216d9e3a6SLisandro Dalcin if (hierr) hypre__global_error = 0; 38316d9e3a6SLisandro Dalcin 38416d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,sbv,bv); 38516d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,sxv,xv); 38616d9e3a6SLisandro Dalcin ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr); 38716d9e3a6SLisandro Dalcin ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr); 38816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 38916d9e3a6SLisandro Dalcin } 39016d9e3a6SLisandro Dalcin 391a669f990SJed Brown /* static array length */ 392a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0])) 393a669f990SJed Brown 39416d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"","V","W"}; 3950f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"}; 39616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"}; 39765de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 39865de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[] = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi", 39965de4495SJed Brown "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi", 40065de4495SJed Brown "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination", 40165de4495SJed Brown "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */, 40265de4495SJed Brown "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"}; 4030f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[] = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i", 4040f1074feSSatish Balay "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"}; 40516d9e3a6SLisandro Dalcin #undef __FUNCT__ 40616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG" 40716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc) 40816d9e3a6SLisandro Dalcin { 40916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 41016d9e3a6SLisandro Dalcin PetscErrorCode ierr; 4114ddd07fcSJed Brown PetscInt n,indx,level; 412ace3abfcSBarry Smith PetscBool flg, tmp_truth; 41316d9e3a6SLisandro Dalcin double tmpdbl, twodbl[2]; 41416d9e3a6SLisandro Dalcin 41516d9e3a6SLisandro Dalcin PetscFunctionBegin; 41616d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE BoomerAMG Options");CHKERRQ(ierr); 4174336a9eeSBarry Smith ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr); 41816d9e3a6SLisandro Dalcin if (flg) { 4194336a9eeSBarry Smith jac->cycletype = indx+1; 420fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype)); 42116d9e3a6SLisandro Dalcin } 42216d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr); 42316d9e3a6SLisandro Dalcin if (flg) { 424ce94432eSBarry Smith if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels); 425fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels)); 42616d9e3a6SLisandro Dalcin } 42716d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr); 42816d9e3a6SLisandro Dalcin if (flg) { 429ce94432eSBarry Smith if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter); 430fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 43116d9e3a6SLisandro Dalcin } 4320f1074feSSatish 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); 43316d9e3a6SLisandro Dalcin if (flg) { 43457622a8eSBarry Smith if (jac->tol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %g must be greater than or equal to zero",(double)jac->tol); 435fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 43616d9e3a6SLisandro Dalcin } 43716d9e3a6SLisandro Dalcin 4380f1074feSSatish Balay ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr); 43916d9e3a6SLisandro Dalcin if (flg) { 44057622a8eSBarry Smith if (jac->truncfactor < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %g must be great than or equal zero",(double)jac->truncfactor); 441fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor)); 44216d9e3a6SLisandro Dalcin } 44316d9e3a6SLisandro Dalcin 4440f1074feSSatish 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); 4450f1074feSSatish Balay if (flg) { 44657622a8eSBarry Smith if (jac->pmax < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %g must be greater than or equal to zero",(double)jac->pmax); 447fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax)); 4480f1074feSSatish Balay } 4490f1074feSSatish Balay 4500f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr); 4510f1074feSSatish Balay if (flg) { 45257622a8eSBarry Smith if (jac->agg_nl < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %g must be greater than or equal to zero",(double)jac->agg_nl); 4530f1074feSSatish Balay 454fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl)); 4550f1074feSSatish Balay } 4560f1074feSSatish Balay 4570f1074feSSatish Balay 4580f1074feSSatish 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); 4590f1074feSSatish Balay if (flg) { 46057622a8eSBarry Smith if (jac->agg_num_paths < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %g must be greater than or equal to 1",(double)jac->agg_num_paths); 4610f1074feSSatish Balay 462fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths)); 4630f1074feSSatish Balay } 4640f1074feSSatish Balay 4650f1074feSSatish Balay 46616d9e3a6SLisandro Dalcin ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr); 46716d9e3a6SLisandro Dalcin if (flg) { 46857622a8eSBarry Smith if (jac->strongthreshold < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %g must be great than or equal zero",(double)jac->strongthreshold); 469fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold)); 47016d9e3a6SLisandro Dalcin } 47116d9e3a6SLisandro Dalcin ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr); 47216d9e3a6SLisandro Dalcin if (flg) { 47357622a8eSBarry Smith if (jac->maxrowsum < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be greater than zero",(double)jac->maxrowsum); 47457622a8eSBarry Smith if (jac->maxrowsum > 1.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be less than or equal one",(double)jac->maxrowsum); 475fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum)); 47616d9e3a6SLisandro Dalcin } 47716d9e3a6SLisandro Dalcin 47816d9e3a6SLisandro Dalcin /* Grid sweeps */ 4790f1074feSSatish 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); 48016d9e3a6SLisandro Dalcin if (flg) { 481fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx)); 48216d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 48316d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 4840f1074feSSatish Balay jac->gridsweeps[1] = indx; 4850f1074feSSatish Balay /*defaults coarse to 1 */ 4860f1074feSSatish Balay jac->gridsweeps[2] = 1; 48716d9e3a6SLisandro Dalcin } 4880f1074feSSatish Balay 4890f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr); 49016d9e3a6SLisandro Dalcin if (flg) { 491fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1)); 4920f1074feSSatish Balay jac->gridsweeps[0] = indx; 49316d9e3a6SLisandro Dalcin } 49416d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr); 49516d9e3a6SLisandro Dalcin if (flg) { 496fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2)); 4970f1074feSSatish Balay jac->gridsweeps[1] = indx; 49816d9e3a6SLisandro Dalcin } 4990f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr); 50016d9e3a6SLisandro Dalcin if (flg) { 501fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3)); 5020f1074feSSatish Balay jac->gridsweeps[2] = indx; 50316d9e3a6SLisandro Dalcin } 50416d9e3a6SLisandro Dalcin 50516d9e3a6SLisandro Dalcin /* Relax type */ 506a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 50716d9e3a6SLisandro Dalcin if (flg) { 5080f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 509fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx)); 5100f1074feSSatish Balay /* by default, coarse type set to 9 */ 5110f1074feSSatish Balay jac->relaxtype[2] = 9; 5120f1074feSSatish Balay 51316d9e3a6SLisandro Dalcin } 514a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 51516d9e3a6SLisandro Dalcin if (flg) { 51616d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 517fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1)); 51816d9e3a6SLisandro Dalcin } 519a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr); 52016d9e3a6SLisandro Dalcin if (flg) { 5210f1074feSSatish Balay jac->relaxtype[1] = indx; 522fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2)); 52316d9e3a6SLisandro Dalcin } 524a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr); 52516d9e3a6SLisandro Dalcin if (flg) { 5260f1074feSSatish Balay jac->relaxtype[2] = indx; 527fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3)); 52816d9e3a6SLisandro Dalcin } 52916d9e3a6SLisandro Dalcin 53016d9e3a6SLisandro Dalcin /* Relaxation Weight */ 53116d9e3a6SLisandro 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); 53216d9e3a6SLisandro Dalcin if (flg) { 533fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl)); 53416d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 53516d9e3a6SLisandro Dalcin } 53616d9e3a6SLisandro Dalcin 53716d9e3a6SLisandro Dalcin n = 2; 53816d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 53916d9e3a6SLisandro 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); 54016d9e3a6SLisandro Dalcin if (flg) { 54116d9e3a6SLisandro Dalcin if (n == 2) { 54216d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 543fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx)); 544ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight level: you must provide 2 values separated by a comma (and no space), you provided %d",n); 54516d9e3a6SLisandro Dalcin } 54616d9e3a6SLisandro Dalcin 54716d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 54816d9e3a6SLisandro 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); 54916d9e3a6SLisandro Dalcin if (flg) { 550fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl)); 55116d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 55216d9e3a6SLisandro Dalcin } 55316d9e3a6SLisandro Dalcin 55416d9e3a6SLisandro Dalcin n = 2; 55516d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 55616d9e3a6SLisandro 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); 55716d9e3a6SLisandro Dalcin if (flg) { 55816d9e3a6SLisandro Dalcin if (n == 2) { 55916d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 560fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx)); 561ce94432eSBarry Smith } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight outer level: You must provide 2 values separated by a comma (and no space), you provided %d",n); 56216d9e3a6SLisandro Dalcin } 56316d9e3a6SLisandro Dalcin 56416d9e3a6SLisandro Dalcin /* the Relax Order */ 565acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 56616d9e3a6SLisandro Dalcin 56716d9e3a6SLisandro Dalcin if (flg) { 56816d9e3a6SLisandro Dalcin jac->relaxorder = 0; 569fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder)); 57016d9e3a6SLisandro Dalcin } 571a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr); 57216d9e3a6SLisandro Dalcin if (flg) { 57316d9e3a6SLisandro Dalcin jac->measuretype = indx; 574fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype)); 57516d9e3a6SLisandro Dalcin } 5760f1074feSSatish Balay /* update list length 3/07 */ 577a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr); 57816d9e3a6SLisandro Dalcin if (flg) { 57916d9e3a6SLisandro Dalcin jac->coarsentype = indx; 580fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype)); 58116d9e3a6SLisandro Dalcin } 5820f1074feSSatish Balay 5830f1074feSSatish Balay /* new 3/07 */ 584a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr); 5850f1074feSSatish Balay if (flg) { 5860f1074feSSatish Balay jac->interptype = indx; 587fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype)); 5880f1074feSSatish Balay } 5890f1074feSSatish Balay 590b96a4a96SBarry Smith ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr); 59116d9e3a6SLisandro Dalcin if (flg) { 592b96a4a96SBarry Smith level = 3; 5930298fd71SBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr); 5942fa5cd67SKarl Rupp 595b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 596fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level)); 5972ae77aedSBarry Smith } 5982ae77aedSBarry Smith 599b96a4a96SBarry Smith ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr); 6002ae77aedSBarry Smith if (flg) { 601b96a4a96SBarry Smith level = 3; 6020298fd71SBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr); 6032fa5cd67SKarl Rupp 604b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 605fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level)); 60616d9e3a6SLisandro Dalcin } 6078f87f92bSBarry Smith 608acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 6098f87f92bSBarry Smith if (flg && tmp_truth) { 6108f87f92bSBarry Smith jac->nodal_coarsen = 1; 611fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1)); 6128f87f92bSBarry Smith } 6138f87f92bSBarry Smith 614acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 6158f87f92bSBarry Smith if (flg && tmp_truth) { 6168f87f92bSBarry Smith PetscInt tmp_int; 6178f87f92bSBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr); 6188f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 619fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6)); 620fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1)); 621fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0)); 622fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels)); 6238f87f92bSBarry Smith } 6248f87f92bSBarry Smith 62516d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 62616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 62716d9e3a6SLisandro Dalcin } 62816d9e3a6SLisandro Dalcin 62916d9e3a6SLisandro Dalcin #undef __FUNCT__ 63016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG" 631ace3abfcSBarry 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) 63216d9e3a6SLisandro Dalcin { 63316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 63416d9e3a6SLisandro Dalcin PetscErrorCode ierr; 6354ddd07fcSJed Brown PetscInt oits; 63616d9e3a6SLisandro Dalcin 63716d9e3a6SLisandro Dalcin PetscFunctionBegin; 638dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 639fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter)); 640fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol)); 64116d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 64216d9e3a6SLisandro Dalcin ierr = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr); 64316d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 6448b1f7689SBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits)); 6454d0a8057SBarry Smith *outits = oits; 6464d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 6474d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 648fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 649fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 65016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 65116d9e3a6SLisandro Dalcin } 65216d9e3a6SLisandro Dalcin 65316d9e3a6SLisandro Dalcin 65416d9e3a6SLisandro Dalcin #undef __FUNCT__ 65516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG" 65616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer) 65716d9e3a6SLisandro Dalcin { 65816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 65916d9e3a6SLisandro Dalcin PetscErrorCode ierr; 660ace3abfcSBarry Smith PetscBool iascii; 66116d9e3a6SLisandro Dalcin 66216d9e3a6SLisandro Dalcin PetscFunctionBegin; 663251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 66416d9e3a6SLisandro Dalcin if (iascii) { 66516d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr); 66616d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr); 66716d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr); 66816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr); 66957622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr); 67057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr); 67157622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr); 6720f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr); 6730f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr); 6740f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr); 6750f1074feSSatish Balay 67657622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr); 67716d9e3a6SLisandro Dalcin 6780f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps down %d\n",jac->gridsweeps[0]);CHKERRQ(ierr); 6790f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps up %d\n",jac->gridsweeps[1]);CHKERRQ(ierr); 6800f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps on coarse %d\n",jac->gridsweeps[2]);CHKERRQ(ierr); 68116d9e3a6SLisandro Dalcin 6820f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax down %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr); 6830f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax up %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr); 6840f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax on coarse %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr); 68516d9e3a6SLisandro Dalcin 68657622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax weight (all) %g\n",(double)jac->relaxweight);CHKERRQ(ierr); 68757622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr); 68816d9e3a6SLisandro Dalcin 68916d9e3a6SLisandro Dalcin if (jac->relaxorder) { 69016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr); 69116d9e3a6SLisandro Dalcin } else { 69216d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr); 69316d9e3a6SLisandro Dalcin } 69416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Measure type %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr); 69516d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Coarsen type %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr); 6960f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation type %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr); 6978f87f92bSBarry Smith if (jac->nodal_coarsen) { 6988f87f92bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr); 6998f87f92bSBarry Smith } 7008f87f92bSBarry Smith if (jac->nodal_relax) { 7018f87f92bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr); 7028f87f92bSBarry Smith } 70316d9e3a6SLisandro Dalcin } 70416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 70516d9e3a6SLisandro Dalcin } 70616d9e3a6SLisandro Dalcin 70716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 70816d9e3a6SLisandro Dalcin #undef __FUNCT__ 70916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails" 71016d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc) 71116d9e3a6SLisandro Dalcin { 71216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 71316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 7144ddd07fcSJed Brown PetscInt indx; 715ace3abfcSBarry Smith PetscBool flag; 71616d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"}; 71716d9e3a6SLisandro Dalcin 71816d9e3a6SLisandro Dalcin PetscFunctionBegin; 71916d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE ParaSails Options");CHKERRQ(ierr); 72016d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr); 72116d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr); 7222fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels)); 72316d9e3a6SLisandro Dalcin 72416d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr); 7252fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter)); 72616d9e3a6SLisandro Dalcin 72716d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr); 7282fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal)); 72916d9e3a6SLisandro Dalcin 730acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr); 7312fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging)); 73216d9e3a6SLisandro Dalcin 733acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr); 7342fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse)); 73516d9e3a6SLisandro Dalcin 736a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr); 73716d9e3a6SLisandro Dalcin if (flag) { 73816d9e3a6SLisandro Dalcin jac->symt = indx; 739fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt)); 74016d9e3a6SLisandro Dalcin } 74116d9e3a6SLisandro Dalcin 74216d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 74316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 74416d9e3a6SLisandro Dalcin } 74516d9e3a6SLisandro Dalcin 74616d9e3a6SLisandro Dalcin #undef __FUNCT__ 74716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails" 74816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer) 74916d9e3a6SLisandro Dalcin { 75016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 75116d9e3a6SLisandro Dalcin PetscErrorCode ierr; 752ace3abfcSBarry Smith PetscBool iascii; 75316d9e3a6SLisandro Dalcin const char *symt = 0;; 75416d9e3a6SLisandro Dalcin 75516d9e3a6SLisandro Dalcin PetscFunctionBegin; 756251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 75716d9e3a6SLisandro Dalcin if (iascii) { 75816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails preconditioning\n");CHKERRQ(ierr); 75916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr); 76057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr); 76157622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr); 76257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr); 763ace3abfcSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr); 764ace3abfcSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr); 7652fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 7662fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 7672fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 768ce94432eSBarry Smith else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt); 76916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr); 77016d9e3a6SLisandro Dalcin } 77116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 77216d9e3a6SLisandro Dalcin } 773*4cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/ 774*4cb006feSStefano Zampini #undef __FUNCT__ 775*4cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS" 776*4cb006feSStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc) 777*4cb006feSStefano Zampini { 778*4cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 779*4cb006feSStefano Zampini PetscErrorCode ierr; 780*4cb006feSStefano Zampini PetscInt n; 781*4cb006feSStefano Zampini PetscBool flag,flag2,flag3,flag4; 782*4cb006feSStefano Zampini 783*4cb006feSStefano Zampini PetscFunctionBegin; 784*4cb006feSStefano Zampini ierr = PetscOptionsHead("HYPRE AMS Options");CHKERRQ(ierr); 785*4cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->ams_print,&jac->ams_print,&flag);CHKERRQ(ierr); 786*4cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print)); 787*4cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->ams_max_iter,&jac->ams_max_iter,&flag);CHKERRQ(ierr); 788*4cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter)); 789*4cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_cycle_type","Cycle type for AMS multigrid","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag);CHKERRQ(ierr); 790*4cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type)); 791*4cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->ams_tol,&jac->ams_tol,&flag);CHKERRQ(ierr); 792*4cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol)); 793*4cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->ams_relax_type,&jac->ams_relax_type,&flag);CHKERRQ(ierr); 794*4cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->ams_relax_times,&jac->ams_relax_times,&flag2);CHKERRQ(ierr); 795*4cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->ams_relax_weight,&jac->ams_relax_weight,&flag3);CHKERRQ(ierr); 796*4cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->ams_omega,&jac->ams_omega,&flag4);CHKERRQ(ierr); 797*4cb006feSStefano Zampini if (flag || flag2 || flag3 || flag4) { 798*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type, 799*4cb006feSStefano Zampini jac->ams_relax_times, 800*4cb006feSStefano Zampini jac->ams_relax_weight, 801*4cb006feSStefano Zampini jac->ams_omega)); 802*4cb006feSStefano Zampini } 803*4cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_amg_alpha_theta","Threshold for strong coupling of vector Poisson AMG solver","None",jac->ams_amg_alpha_theta,&jac->ams_amg_alpha_theta,&flag);CHKERRQ(ierr); 804*4cb006feSStefano Zampini n = 5; 805*4cb006feSStefano Zampini ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->ams_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr); 806*4cb006feSStefano Zampini if (flag || flag2) { 807*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0], /* AMG coarsen type */ 808*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[1], /* AMG agg_levels */ 809*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[2], /* AMG relax_type */ 810*4cb006feSStefano Zampini jac->ams_amg_alpha_theta, 811*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[3], /* AMG interp_type */ 812*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[4])); /* AMG Pmax */ 813*4cb006feSStefano Zampini } 814*4cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_amg_beta_theta","Threshold for strong coupling of scalar Poisson AMG solver","None",jac->ams_amg_beta_theta,&jac->ams_amg_beta_theta,&flag);CHKERRQ(ierr); 815*4cb006feSStefano Zampini n = 5; 816*4cb006feSStefano Zampini ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->ams_amg_beta_opts,&n,&flag2);CHKERRQ(ierr); 817*4cb006feSStefano Zampini if (flag || flag2) { 818*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0], /* AMG coarsen type */ 819*4cb006feSStefano Zampini jac->ams_amg_beta_opts[1], /* AMG agg_levels */ 820*4cb006feSStefano Zampini jac->ams_amg_beta_opts[2], /* AMG relax_type */ 821*4cb006feSStefano Zampini jac->ams_amg_beta_theta, 822*4cb006feSStefano Zampini jac->ams_amg_beta_opts[3], /* AMG interp_type */ 823*4cb006feSStefano Zampini jac->ams_amg_beta_opts[4])); /* AMG Pmax */ 824*4cb006feSStefano Zampini } 825*4cb006feSStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 826*4cb006feSStefano Zampini PetscFunctionReturn(0); 827*4cb006feSStefano Zampini } 828*4cb006feSStefano Zampini 829*4cb006feSStefano Zampini #undef __FUNCT__ 830*4cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS" 831*4cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer) 832*4cb006feSStefano Zampini { 833*4cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 834*4cb006feSStefano Zampini PetscErrorCode ierr; 835*4cb006feSStefano Zampini PetscBool iascii; 836*4cb006feSStefano Zampini 837*4cb006feSStefano Zampini PetscFunctionBegin; 838*4cb006feSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 839*4cb006feSStefano Zampini if (iascii) { 840*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS preconditioning\n");CHKERRQ(ierr); 841*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace iterations per application %d\n",jac->ams_max_iter);CHKERRQ(ierr); 842*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr); 843*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace iteration tolerance %g\n",jac->ams_tol);CHKERRQ(ierr); 844*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother type %d\n",jac->ams_relax_type);CHKERRQ(ierr); 845*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: number of smoothing steps %d\n",jac->ams_relax_times);CHKERRQ(ierr); 846*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother weight %g\n",jac->ams_relax_weight);CHKERRQ(ierr); 847*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother omega %g\n",jac->ams_omega);CHKERRQ(ierr); 848*4cb006feSStefano Zampini if (jac->alpha_Poisson) { 849*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr); 850*4cb006feSStefano Zampini } else { 851*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr); 852*4cb006feSStefano Zampini } 853*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG coarsening type %d\n",jac->ams_amg_alpha_opts[0]);CHKERRQ(ierr); 854*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_alpha_opts[1]);CHKERRQ(ierr); 855*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG relaxation type %d\n",jac->ams_amg_alpha_opts[2]);CHKERRQ(ierr); 856*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG interpolation type %d\n",jac->ams_amg_alpha_opts[3]);CHKERRQ(ierr); 857*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_alpha_opts[4]);CHKERRQ(ierr); 858*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG strength threshold %g\n",jac->ams_amg_alpha_theta);CHKERRQ(ierr); 859*4cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 860*4cb006feSStefano Zampini if (jac->beta_Poisson) { 861*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr); 862*4cb006feSStefano Zampini } else { 863*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr); 864*4cb006feSStefano Zampini } 865*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG coarsening type %d\n",jac->ams_amg_beta_opts[0]);CHKERRQ(ierr); 866*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_beta_opts[1]);CHKERRQ(ierr); 867*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG relaxation type %d\n",jac->ams_amg_beta_opts[2]);CHKERRQ(ierr); 868*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG interpolation type %d\n",jac->ams_amg_beta_opts[3]);CHKERRQ(ierr); 869*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_beta_opts[4]);CHKERRQ(ierr); 870*4cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG strength threshold %g\n",jac->ams_amg_beta_theta);CHKERRQ(ierr); 871*4cb006feSStefano Zampini } 872*4cb006feSStefano Zampini } 873*4cb006feSStefano Zampini PetscFunctionReturn(0); 874*4cb006feSStefano Zampini } 875*4cb006feSStefano Zampini 876*4cb006feSStefano Zampini #undef __FUNCT__ 877*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE_AMS" 878*4cb006feSStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE_AMS(PC pc, Mat G) 879*4cb006feSStefano Zampini { 880*4cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 881*4cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_G; 882*4cb006feSStefano Zampini PetscErrorCode ierr; 883*4cb006feSStefano Zampini 884*4cb006feSStefano Zampini PetscFunctionBegin; 885*4cb006feSStefano Zampini /* throw away any discrete gradient if already set */ 886*4cb006feSStefano Zampini if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); 887*4cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr); 888*4cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr); 889*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G))); 890*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr_G)); 891*4cb006feSStefano Zampini PetscFunctionReturn(0); 892*4cb006feSStefano Zampini } 893*4cb006feSStefano Zampini 894*4cb006feSStefano Zampini #undef __FUNCT__ 895*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient" 896*4cb006feSStefano Zampini /*@ 897*4cb006feSStefano Zampini PCHYPRESetDiscreteGradient - Set discrete gradient matrix 898*4cb006feSStefano Zampini 899*4cb006feSStefano Zampini Collective on PC 900*4cb006feSStefano Zampini 901*4cb006feSStefano Zampini Input Parameters: 902*4cb006feSStefano Zampini + pc - the preconditioning context 903*4cb006feSStefano Zampini - G - the discrete gradient 904*4cb006feSStefano Zampini 905*4cb006feSStefano Zampini Level: intermediate 906*4cb006feSStefano Zampini 907*4cb006feSStefano Zampini Notes: G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 908*4cb006feSStefano Zampini Each row of G has 2 nonzeros, with column indexes being the global indexes of edge's endpoints: matrix values are +1 and -1 depending on edge orientation 909*4cb006feSStefano Zampini 910*4cb006feSStefano Zampini .seealso: 911*4cb006feSStefano Zampini @*/ 912*4cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 913*4cb006feSStefano Zampini { 914*4cb006feSStefano Zampini PetscErrorCode ierr; 915*4cb006feSStefano Zampini 916*4cb006feSStefano Zampini PetscFunctionBegin; 917*4cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 918*4cb006feSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 919*4cb006feSStefano Zampini PetscCheckSameComm(pc,1,G,2); 920*4cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr); 921*4cb006feSStefano Zampini PetscFunctionReturn(0); 922*4cb006feSStefano Zampini } 923*4cb006feSStefano Zampini 924*4cb006feSStefano Zampini #undef __FUNCT__ 925*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS" 926*4cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A) 927*4cb006feSStefano Zampini { 928*4cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 929*4cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_alpha_Poisson; 930*4cb006feSStefano Zampini PetscErrorCode ierr; 931*4cb006feSStefano Zampini 932*4cb006feSStefano Zampini PetscFunctionBegin; 933*4cb006feSStefano Zampini /* throw away any matrix if already set */ 934*4cb006feSStefano Zampini if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); 935*4cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr); 936*4cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr); 937*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson))); 938*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson)); 939*4cb006feSStefano Zampini PetscFunctionReturn(0); 940*4cb006feSStefano Zampini } 941*4cb006feSStefano Zampini 942*4cb006feSStefano Zampini #undef __FUNCT__ 943*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix" 944*4cb006feSStefano Zampini /*@ 945*4cb006feSStefano Zampini PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix 946*4cb006feSStefano Zampini 947*4cb006feSStefano Zampini Collective on PC 948*4cb006feSStefano Zampini 949*4cb006feSStefano Zampini Input Parameters: 950*4cb006feSStefano Zampini + pc - the preconditioning context 951*4cb006feSStefano Zampini - A - the matrix 952*4cb006feSStefano Zampini 953*4cb006feSStefano Zampini Level: intermediate 954*4cb006feSStefano Zampini 955*4cb006feSStefano Zampini Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 956*4cb006feSStefano Zampini 957*4cb006feSStefano Zampini .seealso: 958*4cb006feSStefano Zampini @*/ 959*4cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 960*4cb006feSStefano Zampini { 961*4cb006feSStefano Zampini PetscErrorCode ierr; 962*4cb006feSStefano Zampini 963*4cb006feSStefano Zampini PetscFunctionBegin; 964*4cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 965*4cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 966*4cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 967*4cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr); 968*4cb006feSStefano Zampini PetscFunctionReturn(0); 969*4cb006feSStefano Zampini } 970*4cb006feSStefano Zampini 971*4cb006feSStefano Zampini #undef __FUNCT__ 972*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS" 973*4cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A) 974*4cb006feSStefano Zampini { 975*4cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 976*4cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_beta_Poisson; 977*4cb006feSStefano Zampini PetscErrorCode ierr; 978*4cb006feSStefano Zampini 979*4cb006feSStefano Zampini PetscFunctionBegin; 980*4cb006feSStefano Zampini if (!A) { 981*4cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 982*4cb006feSStefano Zampini PetscFunctionReturn(0); 983*4cb006feSStefano Zampini } 984*4cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 985*4cb006feSStefano Zampini /* throw away any matrix if already set */ 986*4cb006feSStefano Zampini if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); 987*4cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr); 988*4cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr); 989*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson))); 990*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson)); 991*4cb006feSStefano Zampini PetscFunctionReturn(0); 992*4cb006feSStefano Zampini } 993*4cb006feSStefano Zampini 994*4cb006feSStefano Zampini #undef __FUNCT__ 995*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix" 996*4cb006feSStefano Zampini /*@ 997*4cb006feSStefano Zampini PCHYPRESetBetaPoissonMatrix - Set Poisson matrix 998*4cb006feSStefano Zampini 999*4cb006feSStefano Zampini Collective on PC 1000*4cb006feSStefano Zampini 1001*4cb006feSStefano Zampini Input Parameters: 1002*4cb006feSStefano Zampini + pc - the preconditioning context 1003*4cb006feSStefano Zampini - A - the matrix 1004*4cb006feSStefano Zampini 1005*4cb006feSStefano Zampini Level: intermediate 1006*4cb006feSStefano Zampini 1007*4cb006feSStefano Zampini Notes: A should be obtained by discretizing the Poisson problem with linear finite elements. 1008*4cb006feSStefano Zampini Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL. 1009*4cb006feSStefano Zampini 1010*4cb006feSStefano Zampini .seealso: 1011*4cb006feSStefano Zampini @*/ 1012*4cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 1013*4cb006feSStefano Zampini { 1014*4cb006feSStefano Zampini PetscErrorCode ierr; 1015*4cb006feSStefano Zampini 1016*4cb006feSStefano Zampini PetscFunctionBegin; 1017*4cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1018*4cb006feSStefano Zampini if (A) { 1019*4cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 1020*4cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 1021*4cb006feSStefano Zampini } 1022*4cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr); 1023*4cb006feSStefano Zampini PetscFunctionReturn(0); 1024*4cb006feSStefano Zampini } 1025*4cb006feSStefano Zampini 1026*4cb006feSStefano Zampini #undef __FUNCT__ 1027*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS" 1028*4cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo) 1029*4cb006feSStefano Zampini { 1030*4cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1031*4cb006feSStefano Zampini HYPRE_ParVector par_ozz,par_zoz,par_zzo; 1032*4cb006feSStefano Zampini PetscErrorCode ierr; 1033*4cb006feSStefano Zampini 1034*4cb006feSStefano Zampini PetscFunctionBegin; 1035*4cb006feSStefano Zampini /* throw away any vector if already set */ 1036*4cb006feSStefano Zampini if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); 1037*4cb006feSStefano Zampini if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); 1038*4cb006feSStefano Zampini if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); 1039*4cb006feSStefano Zampini jac->constants[0] = NULL; 1040*4cb006feSStefano Zampini jac->constants[1] = NULL; 1041*4cb006feSStefano Zampini jac->constants[2] = NULL; 1042*4cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr); 1043*4cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr); 1044*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz))); 1045*4cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr); 1046*4cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr); 1047*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz))); 1048*4cb006feSStefano Zampini if (zzo) { 1049*4cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr); 1050*4cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr); 1051*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo))); 1052*4cb006feSStefano Zampini } 1053*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo)); 1054*4cb006feSStefano Zampini PetscFunctionReturn(0); 1055*4cb006feSStefano Zampini } 1056*4cb006feSStefano Zampini 1057*4cb006feSStefano Zampini #undef __FUNCT__ 1058*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors" 1059*4cb006feSStefano Zampini /*@ 1060*4cb006feSStefano Zampini PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis 1061*4cb006feSStefano Zampini 1062*4cb006feSStefano Zampini Collective on PC 1063*4cb006feSStefano Zampini 1064*4cb006feSStefano Zampini Input Parameters: 1065*4cb006feSStefano Zampini + pc - the preconditioning context 1066*4cb006feSStefano Zampini - ozz - vector representing (1,0,0) (or (1,0) in 2D) 1067*4cb006feSStefano Zampini - zoz - vector representing (0,1,0) (or (0,1) in 2D) 1068*4cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 1069*4cb006feSStefano Zampini 1070*4cb006feSStefano Zampini Level: intermediate 1071*4cb006feSStefano Zampini 1072*4cb006feSStefano Zampini Notes: 1073*4cb006feSStefano Zampini 1074*4cb006feSStefano Zampini .seealso: 1075*4cb006feSStefano Zampini @*/ 1076*4cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 1077*4cb006feSStefano Zampini { 1078*4cb006feSStefano Zampini PetscErrorCode ierr; 1079*4cb006feSStefano Zampini 1080*4cb006feSStefano Zampini PetscFunctionBegin; 1081*4cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1082*4cb006feSStefano Zampini PetscValidHeaderSpecific(ozz,VEC_CLASSID,2); 1083*4cb006feSStefano Zampini PetscValidHeaderSpecific(zoz,VEC_CLASSID,3); 1084*4cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4); 1085*4cb006feSStefano Zampini PetscCheckSameComm(pc,1,ozz,2); 1086*4cb006feSStefano Zampini PetscCheckSameComm(pc,1,zoz,3); 1087*4cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc,1,zzo,4); 1088*4cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr); 1089*4cb006feSStefano Zampini PetscFunctionReturn(0); 1090*4cb006feSStefano Zampini } 1091*4cb006feSStefano Zampini 1092*4cb006feSStefano Zampini #undef __FUNCT__ 1093*4cb006feSStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE_AMS" 1094*4cb006feSStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE_AMS(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 1095*4cb006feSStefano Zampini { 1096*4cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 1097*4cb006feSStefano Zampini Vec tv; 1098*4cb006feSStefano Zampini HYPRE_ParVector par_coords[3]; 1099*4cb006feSStefano Zampini PetscInt i; 1100*4cb006feSStefano Zampini PetscErrorCode ierr; 1101*4cb006feSStefano Zampini 1102*4cb006feSStefano Zampini PetscFunctionBegin; 1103*4cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 1104*4cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); 1105*4cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); 1106*4cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); 1107*4cb006feSStefano Zampini /* set problem's dimension */ 1108*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim)); 1109*4cb006feSStefano Zampini /* compute IJ vector for coordinates */ 1110*4cb006feSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr); 1111*4cb006feSStefano Zampini ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr); 1112*4cb006feSStefano Zampini ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr); 1113*4cb006feSStefano Zampini for (i=0;i<dim;i++) { 1114*4cb006feSStefano Zampini PetscScalar *array; 1115*4cb006feSStefano Zampini PetscInt j; 1116*4cb006feSStefano Zampini 1117*4cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr); 1118*4cb006feSStefano Zampini ierr = VecGetArray(tv,&array);CHKERRQ(ierr); 1119*4cb006feSStefano Zampini for (j=0;j<nloc;j++) { 1120*4cb006feSStefano Zampini array[j] = coords[j*dim+i]; 1121*4cb006feSStefano Zampini } 1122*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array)); 1123*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i])); 1124*4cb006feSStefano Zampini ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr); 1125*4cb006feSStefano Zampini } 1126*4cb006feSStefano Zampini ierr = VecDestroy(&tv);CHKERRQ(ierr); 1127*4cb006feSStefano Zampini /* pass parCSR vectors to AMS solver */ 1128*4cb006feSStefano Zampini par_coords[0] = NULL; 1129*4cb006feSStefano Zampini par_coords[1] = NULL; 1130*4cb006feSStefano Zampini par_coords[2] = NULL; 1131*4cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0]))); 1132*4cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1]))); 1133*4cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2]))); 1134*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,par_coords[0],par_coords[1],par_coords[2])); 1135*4cb006feSStefano Zampini PetscFunctionReturn(0); 1136*4cb006feSStefano Zampini } 1137*4cb006feSStefano Zampini 113816d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/ 113916d9e3a6SLisandro Dalcin 114016d9e3a6SLisandro Dalcin #undef __FUNCT__ 114116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE" 1142f7a08781SBarry Smith static PetscErrorCode PCHYPREGetType_HYPRE(PC pc,const char *name[]) 114316d9e3a6SLisandro Dalcin { 114416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 114516d9e3a6SLisandro Dalcin 114616d9e3a6SLisandro Dalcin PetscFunctionBegin; 114716d9e3a6SLisandro Dalcin *name = jac->hypre_type; 114816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 114916d9e3a6SLisandro Dalcin } 115016d9e3a6SLisandro Dalcin 115116d9e3a6SLisandro Dalcin #undef __FUNCT__ 115216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE" 1153f7a08781SBarry Smith static PetscErrorCode PCHYPRESetType_HYPRE(PC pc,const char name[]) 115416d9e3a6SLisandro Dalcin { 115516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 115616d9e3a6SLisandro Dalcin PetscErrorCode ierr; 1157ace3abfcSBarry Smith PetscBool flag; 115816d9e3a6SLisandro Dalcin 115916d9e3a6SLisandro Dalcin PetscFunctionBegin; 116016d9e3a6SLisandro Dalcin if (jac->hypre_type) { 116116d9e3a6SLisandro Dalcin ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr); 1162ce94432eSBarry Smith if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set"); 116316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 116416d9e3a6SLisandro Dalcin } else { 116516d9e3a6SLisandro Dalcin ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr); 116616d9e3a6SLisandro Dalcin } 116716d9e3a6SLisandro Dalcin 116816d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 116916d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 117016d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 117116d9e3a6SLisandro Dalcin 117216d9e3a6SLisandro Dalcin ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr); 117316d9e3a6SLisandro Dalcin if (flag) { 1174fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver)); 117516d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 117616d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 117716d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 117816d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 117916d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 118016d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 118116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 118216d9e3a6SLisandro Dalcin } 118316d9e3a6SLisandro Dalcin ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr); 118416d9e3a6SLisandro Dalcin if (flag) { 1185fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver)); 118616d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 118716d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 118816d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 118916d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 119016d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 119116d9e3a6SLisandro Dalcin /* initialize */ 119216d9e3a6SLisandro Dalcin jac->nlevels = 1; 119316d9e3a6SLisandro Dalcin jac->threshhold = .1; 119416d9e3a6SLisandro Dalcin jac->filter = .1; 119516d9e3a6SLisandro Dalcin jac->loadbal = 0; 11962fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE; 11972fa5cd67SKarl Rupp else jac->logging = (int) PETSC_FALSE; 11982fa5cd67SKarl Rupp 119916d9e3a6SLisandro Dalcin jac->ruse = (int) PETSC_FALSE; 120016d9e3a6SLisandro Dalcin jac->symt = 0; 1201fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels)); 1202fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter)); 1203fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal)); 1204fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging)); 1205fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse)); 1206fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt)); 120716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 120816d9e3a6SLisandro Dalcin } 120916d9e3a6SLisandro Dalcin ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr); 121016d9e3a6SLisandro Dalcin if (flag) { 121116d9e3a6SLisandro Dalcin ierr = HYPRE_EuclidCreate(jac->comm_hypre,&jac->hsolver); 121216d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 121316d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Euclid; 121416d9e3a6SLisandro Dalcin jac->destroy = HYPRE_EuclidDestroy; 121516d9e3a6SLisandro Dalcin jac->setup = HYPRE_EuclidSetup; 121616d9e3a6SLisandro Dalcin jac->solve = HYPRE_EuclidSolve; 121716d9e3a6SLisandro Dalcin /* initialization */ 121816d9e3a6SLisandro Dalcin jac->bjilu = PETSC_FALSE; 121916d9e3a6SLisandro Dalcin jac->levels = 1; 122016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 122116d9e3a6SLisandro Dalcin } 122216d9e3a6SLisandro Dalcin ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr); 122316d9e3a6SLisandro Dalcin if (flag) { 122416d9e3a6SLisandro Dalcin ierr = HYPRE_BoomerAMGCreate(&jac->hsolver); 122516d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 122616d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 122716d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 122816d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 122916d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 123016d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 123116d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 123216d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 123316d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 123416d9e3a6SLisandro Dalcin jac->cycletype = 1; 123516d9e3a6SLisandro Dalcin jac->maxlevels = 25; 123616d9e3a6SLisandro Dalcin jac->maxiter = 1; 12378f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 123816d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 123916d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 124016d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 124116d9e3a6SLisandro Dalcin jac->coarsentype = 6; 124216d9e3a6SLisandro Dalcin jac->measuretype = 0; 12430f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 12448f87f92bSBarry Smith jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */ 12450f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 124616d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 124716d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 124816d9e3a6SLisandro Dalcin jac->relaxorder = 1; 12490f1074feSSatish Balay jac->interptype = 0; 12500f1074feSSatish Balay jac->agg_nl = 0; 12510f1074feSSatish Balay jac->pmax = 0; 12520f1074feSSatish Balay jac->truncfactor = 0.0; 12530f1074feSSatish Balay jac->agg_num_paths = 1; 12548f87f92bSBarry Smith 12558f87f92bSBarry Smith jac->nodal_coarsen = 0; 12568f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 12578f87f92bSBarry Smith jac->nodal_relax_levels = 1; 1258fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype)); 1259fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels)); 1260fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 1261fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 1262fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor)); 1263fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold)); 1264fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum)); 1265fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype)); 1266fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype)); 1267fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder)); 1268fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype)); 1269fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl)); 1270fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax)); 1271fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths)); 1272fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0])); /*defaults coarse to 9*/ 1273fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */ 127416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 127516d9e3a6SLisandro Dalcin } 1276*4cb006feSStefano Zampini ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr); 1277*4cb006feSStefano Zampini if (flag) { 1278*4cb006feSStefano Zampini ierr = HYPRE_AMSCreate(&jac->hsolver); 1279*4cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 1280*4cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 1281*4cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 1282*4cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 1283*4cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 1284*4cb006feSStefano Zampini jac->coords[0] = NULL; 1285*4cb006feSStefano Zampini jac->coords[1] = NULL; 1286*4cb006feSStefano Zampini jac->coords[2] = NULL; 1287*4cb006feSStefano Zampini jac->G = NULL; 1288*4cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 1289*4cb006feSStefano Zampini jac->ams_print = 0; 1290*4cb006feSStefano Zampini jac->ams_max_iter = 1; /* used as a preconditioner */ 1291*4cb006feSStefano Zampini jac->ams_cycle_type = 13; 1292*4cb006feSStefano Zampini jac->ams_tol = 0.; /* used as a preconditioner */ 1293*4cb006feSStefano Zampini /* Smoothing options */ 1294*4cb006feSStefano Zampini jac->ams_relax_type = 2; 1295*4cb006feSStefano Zampini jac->ams_relax_times = 1; 1296*4cb006feSStefano Zampini jac->ams_relax_weight = 1.0; 1297*4cb006feSStefano Zampini jac->ams_omega = 1.0; 1298*4cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 1299*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[0] = 10; 1300*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[1] = 1; 1301*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[2] = 8; 1302*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[3] = 6; 1303*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[4] = 4; 1304*4cb006feSStefano Zampini jac->ams_amg_alpha_theta = 0.25; 1305*4cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 1306*4cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 1307*4cb006feSStefano Zampini jac->ams_amg_beta_opts[0] = 10; 1308*4cb006feSStefano Zampini jac->ams_amg_beta_opts[1] = 1; 1309*4cb006feSStefano Zampini jac->ams_amg_beta_opts[2] = 8; 1310*4cb006feSStefano Zampini jac->ams_amg_beta_opts[3] = 6; 1311*4cb006feSStefano Zampini jac->ams_amg_beta_opts[4] = 4; 1312*4cb006feSStefano Zampini jac->ams_amg_beta_theta = 0.25; 1313*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print)); 1314*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter)); 1315*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type)); 1316*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol)); 1317*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type, 1318*4cb006feSStefano Zampini jac->ams_relax_times, 1319*4cb006feSStefano Zampini jac->ams_relax_weight, 1320*4cb006feSStefano Zampini jac->ams_omega)); 1321*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0], /* AMG coarsen type */ 1322*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[1], /* AMG agg_levels */ 1323*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[2], /* AMG relax_type */ 1324*4cb006feSStefano Zampini jac->ams_amg_alpha_theta, 1325*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[3], /* AMG interp_type */ 1326*4cb006feSStefano Zampini jac->ams_amg_alpha_opts[4])); /* AMG Pmax */ 1327*4cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0], /* AMG coarsen type */ 1328*4cb006feSStefano Zampini jac->ams_amg_beta_opts[1], /* AMG agg_levels */ 1329*4cb006feSStefano Zampini jac->ams_amg_beta_opts[2], /* AMG relax_type */ 1330*4cb006feSStefano Zampini jac->ams_amg_beta_theta, 1331*4cb006feSStefano Zampini jac->ams_amg_beta_opts[3], /* AMG interp_type */ 1332*4cb006feSStefano Zampini jac->ams_amg_beta_opts[4])); /* AMG Pmax */ 1333*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE_AMS);CHKERRQ(ierr); 1334*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE_AMS);CHKERRQ(ierr); 1335*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr); 1336*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr); 1337*4cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr); 1338*4cb006feSStefano Zampini PetscFunctionReturn(0); 1339*4cb006feSStefano Zampini } 1340503cfb0cSBarry Smith ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr); 13412fa5cd67SKarl Rupp 13420298fd71SBarry Smith jac->hypre_type = NULL; 1343*4cb006feSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, euclid, boomeramg, ams",name); 134416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 134516d9e3a6SLisandro Dalcin } 134616d9e3a6SLisandro Dalcin 134716d9e3a6SLisandro Dalcin /* 134816d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 134916d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 135016d9e3a6SLisandro Dalcin */ 135116d9e3a6SLisandro Dalcin #undef __FUNCT__ 135216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE" 135316d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE(PC pc) 135416d9e3a6SLisandro Dalcin { 135516d9e3a6SLisandro Dalcin PetscErrorCode ierr; 13564ddd07fcSJed Brown PetscInt indx; 1357*4cb006feSStefano Zampini const char *type[] = {"pilut","parasails","boomeramg","euclid","ams"}; 1358ace3abfcSBarry Smith PetscBool flg; 135916d9e3a6SLisandro Dalcin 136016d9e3a6SLisandro Dalcin PetscFunctionBegin; 136116d9e3a6SLisandro Dalcin ierr = PetscOptionsHead("HYPRE preconditioner options");CHKERRQ(ierr); 1362*4cb006feSStefano Zampini ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,5,"boomeramg",&indx,&flg);CHKERRQ(ierr); 136316d9e3a6SLisandro Dalcin if (flg) { 136416d9e3a6SLisandro Dalcin ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr); 136502a17cd4SBarry Smith } else { 136602a17cd4SBarry Smith ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr); 136716d9e3a6SLisandro Dalcin } 136816d9e3a6SLisandro Dalcin if (pc->ops->setfromoptions) { 136916d9e3a6SLisandro Dalcin ierr = pc->ops->setfromoptions(pc);CHKERRQ(ierr); 137016d9e3a6SLisandro Dalcin } 137116d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 137216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 137316d9e3a6SLisandro Dalcin } 137416d9e3a6SLisandro Dalcin 137516d9e3a6SLisandro Dalcin #undef __FUNCT__ 137616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType" 137716d9e3a6SLisandro Dalcin /*@C 137816d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 137916d9e3a6SLisandro Dalcin 138016d9e3a6SLisandro Dalcin Input Parameters: 138116d9e3a6SLisandro Dalcin + pc - the preconditioner context 1382*4cb006feSStefano Zampini - name - either pilut, parasails, boomeramg, euclid, ams 138316d9e3a6SLisandro Dalcin 138416d9e3a6SLisandro Dalcin Options Database Keys: 1385*4cb006feSStefano Zampini -pc_hypre_type - One of pilut, parasails, boomeramg, euclid, ams 138616d9e3a6SLisandro Dalcin 138716d9e3a6SLisandro Dalcin Level: intermediate 138816d9e3a6SLisandro Dalcin 138916d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 139016d9e3a6SLisandro Dalcin PCHYPRE 139116d9e3a6SLisandro Dalcin 139216d9e3a6SLisandro Dalcin @*/ 13937087cfbeSBarry Smith PetscErrorCode PCHYPRESetType(PC pc,const char name[]) 139416d9e3a6SLisandro Dalcin { 13954ac538c5SBarry Smith PetscErrorCode ierr; 139616d9e3a6SLisandro Dalcin 139716d9e3a6SLisandro Dalcin PetscFunctionBegin; 13980700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 139916d9e3a6SLisandro Dalcin PetscValidCharPointer(name,2); 14004ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr); 140116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 140216d9e3a6SLisandro Dalcin } 140316d9e3a6SLisandro Dalcin 140416d9e3a6SLisandro Dalcin #undef __FUNCT__ 140516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType" 140616d9e3a6SLisandro Dalcin /*@C 140716d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 140816d9e3a6SLisandro Dalcin 140916d9e3a6SLisandro Dalcin Input Parameter: 141016d9e3a6SLisandro Dalcin . pc - the preconditioner context 141116d9e3a6SLisandro Dalcin 141216d9e3a6SLisandro Dalcin Output Parameter: 1413*4cb006feSStefano Zampini . name - either pilut, parasails, boomeramg, euclid, ams 141416d9e3a6SLisandro Dalcin 141516d9e3a6SLisandro Dalcin Level: intermediate 141616d9e3a6SLisandro Dalcin 141716d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC, 141816d9e3a6SLisandro Dalcin PCHYPRE 141916d9e3a6SLisandro Dalcin 142016d9e3a6SLisandro Dalcin @*/ 14217087cfbeSBarry Smith PetscErrorCode PCHYPREGetType(PC pc,const char *name[]) 142216d9e3a6SLisandro Dalcin { 14234ac538c5SBarry Smith PetscErrorCode ierr; 142416d9e3a6SLisandro Dalcin 142516d9e3a6SLisandro Dalcin PetscFunctionBegin; 14260700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 142716d9e3a6SLisandro Dalcin PetscValidPointer(name,2); 14284ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr); 142916d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 143016d9e3a6SLisandro Dalcin } 143116d9e3a6SLisandro Dalcin 143216d9e3a6SLisandro Dalcin /*MC 143316d9e3a6SLisandro Dalcin PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre 143416d9e3a6SLisandro Dalcin 143516d9e3a6SLisandro Dalcin Options Database Keys: 1436*4cb006feSStefano Zampini + -pc_hypre_type - One of pilut, parasails, boomeramg, euclid, ams 143716d9e3a6SLisandro Dalcin - Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX 143816d9e3a6SLisandro Dalcin preconditioner 143916d9e3a6SLisandro Dalcin 144016d9e3a6SLisandro Dalcin Level: intermediate 144116d9e3a6SLisandro Dalcin 144216d9e3a6SLisandro Dalcin Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()), 144316d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 144416d9e3a6SLisandro Dalcin or with PetscOptionsSetValue(), there are no functions to set them) 144516d9e3a6SLisandro Dalcin 144616d9e3a6SLisandro Dalcin The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations 14470f1074feSSatish Balay (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if 14480f1074feSSatish Balay -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner 14490f1074feSSatish Balay (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of 14508f87f92bSBarry Smith iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations 14510f1074feSSatish Balay and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10 14520f1074feSSatish Balay then AT MOST twenty V-cycles of boomeramg will be called. 145316d9e3a6SLisandro Dalcin 14540f1074feSSatish Balay Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation 14550f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 14560f1074feSSatish Balay Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi. 145716d9e3a6SLisandro Dalcin If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly 145816d9e3a6SLisandro Dalcin and use -ksp_max_it to control the number of V-cycles. 145916d9e3a6SLisandro Dalcin (see the PETSc FAQ.html at the PETSc website under the Documentation tab). 146016d9e3a6SLisandro Dalcin 146116d9e3a6SLisandro Dalcin 2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option 146216d9e3a6SLisandro Dalcin -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L. 146316d9e3a6SLisandro Dalcin 14649e5bc791SBarry Smith See PCPFMG for access to the hypre Struct PFMG solver 14659e5bc791SBarry Smith 146616d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 14679e5bc791SBarry Smith PCHYPRESetType(), PCPFMG 146816d9e3a6SLisandro Dalcin 146916d9e3a6SLisandro Dalcin M*/ 147016d9e3a6SLisandro Dalcin 147116d9e3a6SLisandro Dalcin #undef __FUNCT__ 147216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE" 14738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 147416d9e3a6SLisandro Dalcin { 147516d9e3a6SLisandro Dalcin PC_HYPRE *jac; 147616d9e3a6SLisandro Dalcin PetscErrorCode ierr; 147716d9e3a6SLisandro Dalcin 147816d9e3a6SLisandro Dalcin PetscFunctionBegin; 1479b00a9115SJed Brown ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 14802fa5cd67SKarl Rupp 148116d9e3a6SLisandro Dalcin pc->data = jac; 148216d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 148316d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 148416d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 148516d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 148616d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 14870298fd71SBarry Smith jac->hypre_type = NULL; 1488*4cb006feSStefano Zampini jac->coords[0] = NULL; 1489*4cb006feSStefano Zampini jac->coords[1] = NULL; 1490*4cb006feSStefano Zampini jac->coords[2] = NULL; 1491*4cb006feSStefano Zampini jac->constants[0] = NULL; 1492*4cb006feSStefano Zampini jac->constants[1] = NULL; 1493*4cb006feSStefano Zampini jac->constants[2] = NULL; 149416d9e3a6SLisandro Dalcin /* duplicate communicator for hypre */ 1495ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr); 1496bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr); 1497bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr); 149816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 149916d9e3a6SLisandro Dalcin } 1500ebc551c0SBarry Smith 1501f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/ 1502f91d8e95SBarry Smith 1503b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */ 1504b45d2f2cSJed Brown #include <petsc-private/matimpl.h> 1505ebc551c0SBarry Smith 1506ebc551c0SBarry Smith typedef struct { 150768326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 1508f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 15099e5bc791SBarry Smith 15109e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 15114ddd07fcSJed Brown PetscInt its; 15129e5bc791SBarry Smith double tol; 15134ddd07fcSJed Brown PetscInt relax_type; 15144ddd07fcSJed Brown PetscInt rap_type; 15154ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 15164ddd07fcSJed Brown PetscInt max_levels; 1517ebc551c0SBarry Smith } PC_PFMG; 1518ebc551c0SBarry Smith 1519ebc551c0SBarry Smith #undef __FUNCT__ 1520ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG" 1521ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc) 1522ebc551c0SBarry Smith { 1523ebc551c0SBarry Smith PetscErrorCode ierr; 1524f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1525ebc551c0SBarry Smith 1526ebc551c0SBarry Smith PetscFunctionBegin; 15272fa5cd67SKarl Rupp if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver)); 1528f91d8e95SBarry Smith ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr); 1529c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 1530ebc551c0SBarry Smith PetscFunctionReturn(0); 1531ebc551c0SBarry Smith } 1532ebc551c0SBarry Smith 15339e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"}; 15349e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"}; 15359e5bc791SBarry Smith 1536ebc551c0SBarry Smith #undef __FUNCT__ 1537ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG" 1538ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer) 1539ebc551c0SBarry Smith { 1540ebc551c0SBarry Smith PetscErrorCode ierr; 1541ace3abfcSBarry Smith PetscBool iascii; 1542f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1543ebc551c0SBarry Smith 1544ebc551c0SBarry Smith PetscFunctionBegin; 1545251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 15469e5bc791SBarry Smith if (iascii) { 15479e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG preconditioning\n");CHKERRQ(ierr); 15489e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr); 15499e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr); 15509e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr); 15519e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr); 15529e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr); 15533b46a515SGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr); 15549e5bc791SBarry Smith } 1555ebc551c0SBarry Smith PetscFunctionReturn(0); 1556ebc551c0SBarry Smith } 1557ebc551c0SBarry Smith 15589e5bc791SBarry Smith 1559ebc551c0SBarry Smith #undef __FUNCT__ 1560ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG" 1561ebc551c0SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PC pc) 1562ebc551c0SBarry Smith { 1563ebc551c0SBarry Smith PetscErrorCode ierr; 1564f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1565ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1566ebc551c0SBarry Smith 1567ebc551c0SBarry Smith PetscFunctionBegin; 1568ebc551c0SBarry Smith ierr = PetscOptionsHead("PFMG options");CHKERRQ(ierr); 15690298fd71SBarry Smith ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr); 157068326731SBarry Smith if (flg) { 1571a0324ebeSBarry Smith int level=3; 1572fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level)); 157368326731SBarry Smith } 15740298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr); 1575fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its)); 15760298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_StructPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr); 1577fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax)); 15780298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_StructPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr); 1579fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax)); 15809e5bc791SBarry Smith 15810298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr); 1582fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels)); 15833b46a515SGlenn Hammond 15840298fd71SBarry Smith ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr); 1585fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol)); 15860298fd71SBarry Smith ierr = PetscOptionsEList("-pc_pfmg_relax_type","Relax type for the up and down cycles","HYPRE_StructPFMGSetRelaxType",PFMGRelaxType,ALEN(PFMGRelaxType),PFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr); 1587fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type)); 15880298fd71SBarry Smith ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr); 1589fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type)); 1590ebc551c0SBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 1591ebc551c0SBarry Smith PetscFunctionReturn(0); 1592ebc551c0SBarry Smith } 1593ebc551c0SBarry Smith 1594f91d8e95SBarry Smith #undef __FUNCT__ 1595f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG" 1596f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y) 1597f91d8e95SBarry Smith { 1598f91d8e95SBarry Smith PetscErrorCode ierr; 1599f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1600f91d8e95SBarry Smith PetscScalar *xx,*yy; 16014ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 160268326731SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 1603f91d8e95SBarry Smith 1604f91d8e95SBarry Smith PetscFunctionBegin; 1605dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1606aa219208SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1607f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 1608f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 1609f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 1610f91d8e95SBarry Smith 1611f91d8e95SBarry Smith /* copy x values over to hypre */ 1612fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0)); 1613f91d8e95SBarry Smith ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 16148b1f7689SBarry Smith PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,xx)); 1615f91d8e95SBarry Smith ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 1616fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb)); 1617fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx)); 1618f91d8e95SBarry Smith 1619f91d8e95SBarry Smith /* copy solution values back to PETSc */ 1620f91d8e95SBarry Smith ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 16218b1f7689SBarry Smith PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy)); 1622f91d8e95SBarry Smith ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1623f91d8e95SBarry Smith PetscFunctionReturn(0); 1624f91d8e95SBarry Smith } 1625f91d8e95SBarry Smith 16269e5bc791SBarry Smith #undef __FUNCT__ 16279e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG" 1628ace3abfcSBarry 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) 16299e5bc791SBarry Smith { 16309e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG*)pc->data; 16319e5bc791SBarry Smith PetscErrorCode ierr; 16324ddd07fcSJed Brown PetscInt oits; 16339e5bc791SBarry Smith 16349e5bc791SBarry Smith PetscFunctionBegin; 1635dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1636fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its)); 1637fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol)); 16389e5bc791SBarry Smith 16399e5bc791SBarry Smith ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr); 16408b1f7689SBarry Smith PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits)); 16419e5bc791SBarry Smith *outits = oits; 16429e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 16439e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1644fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol)); 1645fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its)); 16469e5bc791SBarry Smith PetscFunctionReturn(0); 16479e5bc791SBarry Smith } 16489e5bc791SBarry Smith 16499e5bc791SBarry Smith 16503a32d3dbSGlenn Hammond #undef __FUNCT__ 16513a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG" 16523a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc) 16533a32d3dbSGlenn Hammond { 16543a32d3dbSGlenn Hammond PetscErrorCode ierr; 16553a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG*) pc->data; 16563a32d3dbSGlenn Hammond Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 1657ace3abfcSBarry Smith PetscBool flg; 16583a32d3dbSGlenn Hammond 16593a32d3dbSGlenn Hammond PetscFunctionBegin; 1660251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr); 1661ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner"); 16623a32d3dbSGlenn Hammond 16633a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 16642fa5cd67SKarl Rupp if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver)); 1665fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver)); 16663a32d3dbSGlenn Hammond ierr = PCSetFromOptions_PFMG(pc);CHKERRQ(ierr); 1667fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx)); 1668fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver)); 16693a32d3dbSGlenn Hammond PetscFunctionReturn(0); 16703a32d3dbSGlenn Hammond } 16713a32d3dbSGlenn Hammond 1672ebc551c0SBarry Smith 1673ebc551c0SBarry Smith /*MC 1674ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 1675ebc551c0SBarry Smith 1676ebc551c0SBarry Smith Level: advanced 1677ebc551c0SBarry Smith 16789e5bc791SBarry Smith Options Database: 16799e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner 16809e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid 16819e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid 16829e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG 16839e5bc791SBarry 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 16849e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 1685f91d8e95SBarry Smith 16869e5bc791SBarry Smith Notes: This is for CELL-centered descretizations 16879e5bc791SBarry Smith 16888e395302SJed Brown This must be used with the MATHYPRESTRUCT matrix type. 1689aa219208SBarry Smith This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA. 16909e5bc791SBarry Smith 16919e5bc791SBarry Smith .seealso: PCMG, MATHYPRESTRUCT 1692ebc551c0SBarry Smith M*/ 1693ebc551c0SBarry Smith 1694ebc551c0SBarry Smith #undef __FUNCT__ 1695ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG" 16968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 1697ebc551c0SBarry Smith { 1698ebc551c0SBarry Smith PetscErrorCode ierr; 1699ebc551c0SBarry Smith PC_PFMG *ex; 1700ebc551c0SBarry Smith 1701ebc551c0SBarry Smith PetscFunctionBegin; 1702b00a9115SJed Brown ierr = PetscNew(&ex);CHKERRQ(ierr); \ 170368326731SBarry Smith pc->data = ex; 1704ebc551c0SBarry Smith 17059e5bc791SBarry Smith ex->its = 1; 17069e5bc791SBarry Smith ex->tol = 1.e-8; 17079e5bc791SBarry Smith ex->relax_type = 1; 17089e5bc791SBarry Smith ex->rap_type = 0; 17099e5bc791SBarry Smith ex->num_pre_relax = 1; 17109e5bc791SBarry Smith ex->num_post_relax = 1; 17113b46a515SGlenn Hammond ex->max_levels = 0; 17129e5bc791SBarry Smith 1713ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 1714ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 1715ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 1716f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 17179e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 171868326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 17192fa5cd67SKarl Rupp 1720ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr); 1721fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver)); 1722ebc551c0SBarry Smith PetscFunctionReturn(0); 1723ebc551c0SBarry Smith } 1724d851a50bSGlenn Hammond 1725325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/ 1726325fc9f4SBarry Smith 1727d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 1728d851a50bSGlenn Hammond typedef struct { 1729d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 1730d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 1731d851a50bSGlenn Hammond 1732d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 17334ddd07fcSJed Brown PetscInt its; 1734d851a50bSGlenn Hammond double tol; 17354ddd07fcSJed Brown PetscInt relax_type; 17364ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 1737d851a50bSGlenn Hammond } PC_SysPFMG; 1738d851a50bSGlenn Hammond 1739d851a50bSGlenn Hammond #undef __FUNCT__ 1740d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG" 1741d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc) 1742d851a50bSGlenn Hammond { 1743d851a50bSGlenn Hammond PetscErrorCode ierr; 1744d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1745d851a50bSGlenn Hammond 1746d851a50bSGlenn Hammond PetscFunctionBegin; 17472fa5cd67SKarl Rupp if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver)); 1748d851a50bSGlenn Hammond ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr); 1749c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 1750d851a50bSGlenn Hammond PetscFunctionReturn(0); 1751d851a50bSGlenn Hammond } 1752d851a50bSGlenn Hammond 1753d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"}; 1754d851a50bSGlenn Hammond 1755d851a50bSGlenn Hammond #undef __FUNCT__ 1756d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG" 1757d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer) 1758d851a50bSGlenn Hammond { 1759d851a50bSGlenn Hammond PetscErrorCode ierr; 1760ace3abfcSBarry Smith PetscBool iascii; 1761d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1762d851a50bSGlenn Hammond 1763d851a50bSGlenn Hammond PetscFunctionBegin; 1764251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1765d851a50bSGlenn Hammond if (iascii) { 1766d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr); 1767d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr); 1768d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr); 1769d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr); 1770d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr); 1771d851a50bSGlenn Hammond } 1772d851a50bSGlenn Hammond PetscFunctionReturn(0); 1773d851a50bSGlenn Hammond } 1774d851a50bSGlenn Hammond 1775d851a50bSGlenn Hammond 1776d851a50bSGlenn Hammond #undef __FUNCT__ 1777d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG" 1778d851a50bSGlenn Hammond PetscErrorCode PCSetFromOptions_SysPFMG(PC pc) 1779d851a50bSGlenn Hammond { 1780d851a50bSGlenn Hammond PetscErrorCode ierr; 1781d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1782ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1783d851a50bSGlenn Hammond 1784d851a50bSGlenn Hammond PetscFunctionBegin; 1785d851a50bSGlenn Hammond ierr = PetscOptionsHead("SysPFMG options");CHKERRQ(ierr); 17860298fd71SBarry Smith ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr); 1787d851a50bSGlenn Hammond if (flg) { 1788d851a50bSGlenn Hammond int level=3; 1789fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level)); 1790d851a50bSGlenn Hammond } 17910298fd71SBarry Smith ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr); 1792fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its)); 17930298fd71SBarry Smith ierr = PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr); 1794fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax)); 17950298fd71SBarry Smith ierr = PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr); 1796fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax)); 1797d851a50bSGlenn Hammond 17980298fd71SBarry Smith ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr); 1799fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol)); 18000298fd71SBarry Smith ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,4,SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr); 1801fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type)); 1802d851a50bSGlenn Hammond ierr = PetscOptionsTail();CHKERRQ(ierr); 1803d851a50bSGlenn Hammond PetscFunctionReturn(0); 1804d851a50bSGlenn Hammond } 1805d851a50bSGlenn Hammond 1806d851a50bSGlenn Hammond #undef __FUNCT__ 1807d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG" 1808d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y) 1809d851a50bSGlenn Hammond { 1810d851a50bSGlenn Hammond PetscErrorCode ierr; 1811d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1812d851a50bSGlenn Hammond PetscScalar *xx,*yy; 18134ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 1814d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 18154ddd07fcSJed Brown PetscInt ordering= mx->dofs_order; 18164ddd07fcSJed Brown PetscInt nvars = mx->nvars; 18174ddd07fcSJed Brown PetscInt part = 0; 18184ddd07fcSJed Brown PetscInt size; 18194ddd07fcSJed Brown PetscInt i; 1820d851a50bSGlenn Hammond 1821d851a50bSGlenn Hammond PetscFunctionBegin; 1822dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1823aa219208SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1824d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 1825d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 1826d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 1827d851a50bSGlenn Hammond 1828d851a50bSGlenn Hammond size = 1; 18292fa5cd67SKarl Rupp for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1); 18302fa5cd67SKarl Rupp 1831d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 1832d851a50bSGlenn Hammond if (ordering) { 1833fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0)); 1834d851a50bSGlenn Hammond ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 18358b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,xx+(size*i))); 1836d851a50bSGlenn Hammond ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 1837fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b)); 1838fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x)); 1839fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1840d851a50bSGlenn Hammond 1841d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 1842d851a50bSGlenn Hammond ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 18438b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i))); 1844d851a50bSGlenn Hammond ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1845a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 1846d851a50bSGlenn Hammond PetscScalar *z; 18474ddd07fcSJed Brown PetscInt j, k; 1848d851a50bSGlenn Hammond 1849785e854fSJed Brown ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr); 1850fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0)); 1851d851a50bSGlenn Hammond ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 1852d851a50bSGlenn Hammond 1853d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 1854d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 1855d851a50bSGlenn Hammond k= i*nvars; 18562fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j]; 1857d851a50bSGlenn Hammond } 18588b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i))); 1859d851a50bSGlenn Hammond ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 1860fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b)); 1861fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1862d851a50bSGlenn Hammond 1863d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 1864d851a50bSGlenn Hammond ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 18658b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i))); 1866d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 1867d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 1868d851a50bSGlenn Hammond k= i*nvars; 18692fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i]; 1870d851a50bSGlenn Hammond } 1871d851a50bSGlenn Hammond ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1872d851a50bSGlenn Hammond ierr = PetscFree(z);CHKERRQ(ierr); 1873d851a50bSGlenn Hammond } 1874d851a50bSGlenn Hammond PetscFunctionReturn(0); 1875d851a50bSGlenn Hammond } 1876d851a50bSGlenn Hammond 1877d851a50bSGlenn Hammond #undef __FUNCT__ 1878d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG" 1879ace3abfcSBarry 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) 1880d851a50bSGlenn Hammond { 1881d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG*)pc->data; 1882d851a50bSGlenn Hammond PetscErrorCode ierr; 18834ddd07fcSJed Brown PetscInt oits; 1884d851a50bSGlenn Hammond 1885d851a50bSGlenn Hammond PetscFunctionBegin; 1886dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1887fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its)); 1888fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol)); 1889d851a50bSGlenn Hammond ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr); 18908b1f7689SBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits)); 1891d851a50bSGlenn Hammond *outits = oits; 1892d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 1893d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 1894fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol)); 1895fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its)); 1896d851a50bSGlenn Hammond PetscFunctionReturn(0); 1897d851a50bSGlenn Hammond } 1898d851a50bSGlenn Hammond 1899d851a50bSGlenn Hammond 1900d851a50bSGlenn Hammond #undef __FUNCT__ 1901d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG" 1902d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc) 1903d851a50bSGlenn Hammond { 1904d851a50bSGlenn Hammond PetscErrorCode ierr; 1905d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1906d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 1907ace3abfcSBarry Smith PetscBool flg; 1908d851a50bSGlenn Hammond 1909d851a50bSGlenn Hammond PetscFunctionBegin; 1910251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr); 1911ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner"); 1912d851a50bSGlenn Hammond 1913d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 19142fa5cd67SKarl Rupp if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver)); 1915fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver)); 1916d851a50bSGlenn Hammond ierr = PCSetFromOptions_SysPFMG(pc);CHKERRQ(ierr); 1917fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver)); 1918fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1919d851a50bSGlenn Hammond PetscFunctionReturn(0); 1920d851a50bSGlenn Hammond } 1921d851a50bSGlenn Hammond 1922d851a50bSGlenn Hammond 1923d851a50bSGlenn Hammond /*MC 1924d851a50bSGlenn Hammond PCSysPFMG - the hypre SysPFMG multigrid solver 1925d851a50bSGlenn Hammond 1926d851a50bSGlenn Hammond Level: advanced 1927d851a50bSGlenn Hammond 1928d851a50bSGlenn Hammond Options Database: 1929d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner 1930d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid 1931d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid 1932d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG 1933d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel 1934d851a50bSGlenn Hammond 1935d851a50bSGlenn Hammond Notes: This is for CELL-centered descretizations 1936d851a50bSGlenn Hammond 1937f6680f47SSatish Balay This must be used with the MATHYPRESSTRUCT matrix type. 1938aa219208SBarry Smith This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA. 1939d851a50bSGlenn Hammond Also, only cell-centered variables. 1940d851a50bSGlenn Hammond 1941d851a50bSGlenn Hammond .seealso: PCMG, MATHYPRESSTRUCT 1942d851a50bSGlenn Hammond M*/ 1943d851a50bSGlenn Hammond 1944d851a50bSGlenn Hammond #undef __FUNCT__ 1945d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG" 19468cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 1947d851a50bSGlenn Hammond { 1948d851a50bSGlenn Hammond PetscErrorCode ierr; 1949d851a50bSGlenn Hammond PC_SysPFMG *ex; 1950d851a50bSGlenn Hammond 1951d851a50bSGlenn Hammond PetscFunctionBegin; 1952b00a9115SJed Brown ierr = PetscNew(&ex);CHKERRQ(ierr); \ 1953d851a50bSGlenn Hammond pc->data = ex; 1954d851a50bSGlenn Hammond 1955d851a50bSGlenn Hammond ex->its = 1; 1956d851a50bSGlenn Hammond ex->tol = 1.e-8; 1957d851a50bSGlenn Hammond ex->relax_type = 1; 1958d851a50bSGlenn Hammond ex->num_pre_relax = 1; 1959d851a50bSGlenn Hammond ex->num_post_relax = 1; 1960d851a50bSGlenn Hammond 1961d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 1962d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 1963d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 1964d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 1965d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 1966d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 19672fa5cd67SKarl Rupp 1968ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr); 1969fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver)); 1970d851a50bSGlenn Hammond PetscFunctionReturn(0); 1971d851a50bSGlenn Hammond } 1972