116d9e3a6SLisandro Dalcin 216d9e3a6SLisandro Dalcin /* 316d9e3a6SLisandro Dalcin Provides an interface to the LLNL package hypre 416d9e3a6SLisandro Dalcin */ 50f1074feSSatish Balay 60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */ 70f1074feSSatish Balay 8b45d2f2cSJed Brown #include <petsc-private/pcimpl.h> /*I "petscpc.h" I*/ 9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h> 104cb006feSStefano Zampini #include <_hypre_parcsr_ls.h> 1116d9e3a6SLisandro Dalcin 12dff31646SBarry Smith static PetscBool cite = PETSC_FALSE; 131f817a21SBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n title = {{\\sl hypre}: High Performance Preconditioners},\n organization = {Lawrence Livermore National Laboratory},\n note = {\\url{http://www.llnl.gov/CASC/hypre/}}\n}\n"; 141f817a21SBarry Smith 1516d9e3a6SLisandro Dalcin /* 1616d9e3a6SLisandro Dalcin Private context (data structure) for the preconditioner. 1716d9e3a6SLisandro Dalcin */ 1816d9e3a6SLisandro Dalcin typedef struct { 1916d9e3a6SLisandro Dalcin HYPRE_Solver hsolver; 2016d9e3a6SLisandro Dalcin HYPRE_IJMatrix ij; 2116d9e3a6SLisandro Dalcin HYPRE_IJVector b,x; 2216d9e3a6SLisandro Dalcin 234ddd07fcSJed Brown HYPRE_Int (*destroy)(HYPRE_Solver); 244ddd07fcSJed Brown HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 254ddd07fcSJed Brown HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector); 2616d9e3a6SLisandro Dalcin 2716d9e3a6SLisandro Dalcin MPI_Comm comm_hypre; 2816d9e3a6SLisandro Dalcin char *hypre_type; 2916d9e3a6SLisandro Dalcin 3016d9e3a6SLisandro Dalcin /* options for Pilut and BoomerAMG*/ 314ddd07fcSJed Brown PetscInt maxiter; 3216d9e3a6SLisandro Dalcin double tol; 3316d9e3a6SLisandro Dalcin 3416d9e3a6SLisandro Dalcin /* options for Pilut */ 354ddd07fcSJed Brown PetscInt factorrowsize; 3616d9e3a6SLisandro Dalcin 3716d9e3a6SLisandro Dalcin /* options for ParaSails */ 384ddd07fcSJed Brown PetscInt nlevels; 3916d9e3a6SLisandro Dalcin double threshhold; 4016d9e3a6SLisandro Dalcin double filter; 414ddd07fcSJed Brown PetscInt sym; 4216d9e3a6SLisandro Dalcin double loadbal; 434ddd07fcSJed Brown PetscInt logging; 444ddd07fcSJed Brown PetscInt ruse; 454ddd07fcSJed Brown PetscInt symt; 4616d9e3a6SLisandro Dalcin 4722b6d1caSBarry Smith /* options for BoomerAMG */ 48ace3abfcSBarry Smith PetscBool printstatistics; 4916d9e3a6SLisandro Dalcin 5016d9e3a6SLisandro Dalcin /* options for BoomerAMG */ 514ddd07fcSJed Brown PetscInt cycletype; 524ddd07fcSJed Brown PetscInt maxlevels; 5316d9e3a6SLisandro Dalcin double strongthreshold; 5416d9e3a6SLisandro Dalcin double maxrowsum; 554ddd07fcSJed Brown PetscInt gridsweeps[3]; 564ddd07fcSJed Brown PetscInt coarsentype; 574ddd07fcSJed Brown PetscInt measuretype; 584ddd07fcSJed Brown PetscInt relaxtype[3]; 5916d9e3a6SLisandro Dalcin double relaxweight; 6016d9e3a6SLisandro Dalcin double outerrelaxweight; 614ddd07fcSJed Brown PetscInt relaxorder; 6216d9e3a6SLisandro Dalcin double truncfactor; 63ace3abfcSBarry Smith PetscBool applyrichardson; 644ddd07fcSJed Brown PetscInt pmax; 654ddd07fcSJed Brown PetscInt interptype; 664ddd07fcSJed Brown PetscInt agg_nl; 674ddd07fcSJed Brown PetscInt agg_num_paths; 684ddd07fcSJed Brown PetscInt nodal_coarsen; 69ace3abfcSBarry Smith PetscBool nodal_relax; 704ddd07fcSJed Brown PetscInt nodal_relax_levels; 714cb006feSStefano Zampini 724cb006feSStefano Zampini /* options for AMS */ 734cb006feSStefano Zampini PetscInt ams_print; 744cb006feSStefano Zampini PetscInt ams_max_iter; 754cb006feSStefano Zampini PetscInt ams_cycle_type; 764cb006feSStefano Zampini PetscReal ams_tol; 774cb006feSStefano Zampini PetscInt ams_relax_type; 784cb006feSStefano Zampini PetscInt ams_relax_times; 794cb006feSStefano Zampini PetscReal ams_relax_weight; 804cb006feSStefano Zampini PetscReal ams_omega; 814cb006feSStefano Zampini PetscInt ams_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson */ 824cb006feSStefano Zampini PetscReal ams_amg_alpha_theta; /* AMG strength for vector Poisson */ 834cb006feSStefano Zampini PetscInt ams_amg_beta_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson */ 844cb006feSStefano Zampini PetscReal ams_amg_beta_theta; /* AMG strength for scalar Poisson */ 854cb006feSStefano Zampini 864cb006feSStefano Zampini /* additional data */ 874cb006feSStefano Zampini HYPRE_IJVector coords[3]; 884cb006feSStefano Zampini HYPRE_IJVector constants[3]; 894cb006feSStefano Zampini HYPRE_IJMatrix G; 904cb006feSStefano Zampini HYPRE_IJMatrix alpha_Poisson; 914cb006feSStefano Zampini HYPRE_IJMatrix beta_Poisson; 924cb006feSStefano Zampini PetscBool ams_beta_is_zero; 9316d9e3a6SLisandro Dalcin } PC_HYPRE; 9416d9e3a6SLisandro Dalcin 95d2128fa2SBarry Smith #undef __FUNCT__ 96d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver" 97d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver) 98d2128fa2SBarry Smith { 99d2128fa2SBarry Smith PC_HYPRE *jac = (PC_HYPRE*)pc->data; 100d2128fa2SBarry Smith 101d2128fa2SBarry Smith PetscFunctionBegin; 102d2128fa2SBarry Smith *hsolver = jac->hsolver; 103d2128fa2SBarry Smith PetscFunctionReturn(0); 104d2128fa2SBarry Smith } 10516d9e3a6SLisandro Dalcin 10616d9e3a6SLisandro Dalcin #undef __FUNCT__ 10716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE" 10816d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc) 10916d9e3a6SLisandro Dalcin { 11016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 11116d9e3a6SLisandro Dalcin PetscErrorCode ierr; 11216d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 11316d9e3a6SLisandro Dalcin HYPRE_ParVector bv,xv; 11416d9e3a6SLisandro Dalcin PetscInt bs; 11516d9e3a6SLisandro Dalcin 11616d9e3a6SLisandro Dalcin PetscFunctionBegin; 11716d9e3a6SLisandro Dalcin if (!jac->hypre_type) { 11802a17cd4SBarry Smith ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr); 11916d9e3a6SLisandro Dalcin } 1205f5c5b43SBarry Smith 1215f5c5b43SBarry Smith if (pc->setupcalled) { 1225f5c5b43SBarry Smith /* always destroy the old matrix and create a new memory; 1235f5c5b43SBarry Smith hope this does not churn the memory too much. The problem 1245f5c5b43SBarry Smith is I do not know if it is possible to put the matrix back to 1255f5c5b43SBarry Smith its initial state so that we can directly copy the values 1265f5c5b43SBarry Smith the second time through. */ 127fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij)); 1285f5c5b43SBarry Smith jac->ij = 0; 12916d9e3a6SLisandro Dalcin } 1305f5c5b43SBarry Smith 13116d9e3a6SLisandro Dalcin if (!jac->ij) { /* create the matrix the first time through */ 13216d9e3a6SLisandro Dalcin ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr); 13316d9e3a6SLisandro Dalcin } 13416d9e3a6SLisandro Dalcin if (!jac->b) { /* create the vectors the first time through */ 13516d9e3a6SLisandro Dalcin Vec x,b; 1362a7a6963SBarry Smith ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr); 13716d9e3a6SLisandro Dalcin ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr); 13816d9e3a6SLisandro Dalcin ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr); 1396bf464f9SBarry Smith ierr = VecDestroy(&x);CHKERRQ(ierr); 1406bf464f9SBarry Smith ierr = VecDestroy(&b);CHKERRQ(ierr); 14116d9e3a6SLisandro Dalcin } 1425f5c5b43SBarry Smith 14316d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 14416d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 14516d9e3a6SLisandro Dalcin ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 1462fa5cd67SKarl Rupp if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs)); 1474cb006feSStefano Zampini } 1484cb006feSStefano Zampini /* special case for AMS */ 1494cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 1504cb006feSStefano Zampini if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either coordinate vectors via PCSetCoordinates() or edge constant vectors via PCHYPRESetEdgeConstantVectors()"); 1514cb006feSStefano Zampini if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient"); 1524cb006feSStefano Zampini } 15316d9e3a6SLisandro Dalcin ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr); 154fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 155fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv)); 156fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv)); 157fd3f9acdSBarry Smith PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr);); 15816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 15916d9e3a6SLisandro Dalcin } 16016d9e3a6SLisandro Dalcin 16116d9e3a6SLisandro Dalcin /* 16216d9e3a6SLisandro Dalcin Replaces the address where the HYPRE vector points to its data with the address of 16316d9e3a6SLisandro Dalcin PETSc's data. Saves the old address so it can be reset when we are finished with it. 16416d9e3a6SLisandro Dalcin Allows use to get the data into a HYPRE vector without the cost of memcopies 16516d9e3a6SLisandro Dalcin */ 16616d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \ 16716d9e3a6SLisandro Dalcin hypre_ParVector *par_vector = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \ 16816d9e3a6SLisandro Dalcin hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); \ 16916d9e3a6SLisandro Dalcin savedvalue = local_vector->data; \ 1700ad7597dSKarl Rupp local_vector->data = newvalue; \ 1710ad7597dSKarl Rupp } 17216d9e3a6SLisandro Dalcin 17316d9e3a6SLisandro Dalcin #undef __FUNCT__ 17416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE" 17516d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x) 17616d9e3a6SLisandro Dalcin { 17716d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 17816d9e3a6SLisandro Dalcin PetscErrorCode ierr; 17916d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 18016d9e3a6SLisandro Dalcin PetscScalar *bv,*xv; 18116d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 18216d9e3a6SLisandro Dalcin PetscScalar *sbv,*sxv; 1834ddd07fcSJed Brown PetscInt hierr; 18416d9e3a6SLisandro Dalcin 18516d9e3a6SLisandro Dalcin PetscFunctionBegin; 186dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 18716d9e3a6SLisandro Dalcin if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);} 18816d9e3a6SLisandro Dalcin ierr = VecGetArray(b,&bv);CHKERRQ(ierr); 18916d9e3a6SLisandro Dalcin ierr = VecGetArray(x,&xv);CHKERRQ(ierr); 19016d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,bv,sbv); 19116d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,xv,sxv); 19216d9e3a6SLisandro Dalcin 193fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 194fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv)); 195fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv)); 196fd3f9acdSBarry Smith PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv); 19765e19b50SBarry Smith if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr); 198fd3f9acdSBarry Smith if (hierr) hypre__global_error = 0;); 19916d9e3a6SLisandro Dalcin 20016d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,sbv,bv); 20116d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,sxv,xv); 20216d9e3a6SLisandro Dalcin ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr); 20316d9e3a6SLisandro Dalcin ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr); 20416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 20516d9e3a6SLisandro Dalcin } 20616d9e3a6SLisandro Dalcin 20716d9e3a6SLisandro Dalcin #undef __FUNCT__ 20816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE" 20916d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc) 21016d9e3a6SLisandro Dalcin { 21116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 21216d9e3a6SLisandro Dalcin PetscErrorCode ierr; 21316d9e3a6SLisandro Dalcin 21416d9e3a6SLisandro Dalcin PetscFunctionBegin; 215fd3f9acdSBarry Smith if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij)); 216fd3f9acdSBarry Smith if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b)); 217fd3f9acdSBarry Smith if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x)); 2184cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); 2194cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); 2204cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); 2214cb006feSStefano Zampini if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); 2224cb006feSStefano Zampini if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); 2234cb006feSStefano Zampini if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); 2244cb006feSStefano Zampini if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); 2254cb006feSStefano Zampini if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); 2264cb006feSStefano Zampini if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); 227226b0620SJed Brown if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr);); 228503cfb0cSBarry Smith ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr); 22916d9e3a6SLisandro Dalcin if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);} 230c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 23116d9e3a6SLisandro Dalcin 23216d9e3a6SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr); 233bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr); 234bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr); 2354cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr); 2364cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2374cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr); 2384cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr); 2394cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr); 24016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 24116d9e3a6SLisandro Dalcin } 24216d9e3a6SLisandro Dalcin 24316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 24416d9e3a6SLisandro Dalcin #undef __FUNCT__ 24516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut" 2468c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc) 24716d9e3a6SLisandro Dalcin { 24816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 24916d9e3a6SLisandro Dalcin PetscErrorCode ierr; 250ace3abfcSBarry Smith PetscBool flag; 25116d9e3a6SLisandro Dalcin 25216d9e3a6SLisandro Dalcin PetscFunctionBegin; 253e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr); 25416d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr); 255fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter)); 25616d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr); 257fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol)); 25816d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr); 259fd3f9acdSBarry Smith if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize)); 26016d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 26116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 26216d9e3a6SLisandro Dalcin } 26316d9e3a6SLisandro Dalcin 26416d9e3a6SLisandro Dalcin #undef __FUNCT__ 26516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut" 26616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer) 26716d9e3a6SLisandro Dalcin { 26816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 26916d9e3a6SLisandro Dalcin PetscErrorCode ierr; 270ace3abfcSBarry Smith PetscBool iascii; 27116d9e3a6SLisandro Dalcin 27216d9e3a6SLisandro Dalcin PetscFunctionBegin; 273251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 27416d9e3a6SLisandro Dalcin if (iascii) { 27516d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut preconditioning\n");CHKERRQ(ierr); 27616d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 27716d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr); 27816d9e3a6SLisandro Dalcin } else { 27916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr); 28016d9e3a6SLisandro Dalcin } 28116d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 28257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr); 28316d9e3a6SLisandro Dalcin } else { 28416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr); 28516d9e3a6SLisandro Dalcin } 28616d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 28716d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr); 28816d9e3a6SLisandro Dalcin } else { 28916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE Pilut: default factor row size \n");CHKERRQ(ierr); 29016d9e3a6SLisandro Dalcin } 29116d9e3a6SLisandro Dalcin } 29216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 29316d9e3a6SLisandro Dalcin } 29416d9e3a6SLisandro Dalcin 29516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 29616d9e3a6SLisandro Dalcin 29716d9e3a6SLisandro Dalcin #undef __FUNCT__ 29816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG" 29916d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x) 30016d9e3a6SLisandro Dalcin { 30116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 30216d9e3a6SLisandro Dalcin PetscErrorCode ierr; 30316d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 30416d9e3a6SLisandro Dalcin PetscScalar *bv,*xv; 30516d9e3a6SLisandro Dalcin HYPRE_ParVector jbv,jxv; 30616d9e3a6SLisandro Dalcin PetscScalar *sbv,*sxv; 3074ddd07fcSJed Brown PetscInt hierr; 30816d9e3a6SLisandro Dalcin 30916d9e3a6SLisandro Dalcin PetscFunctionBegin; 310dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 31116d9e3a6SLisandro Dalcin ierr = VecSet(x,0.0);CHKERRQ(ierr); 31216d9e3a6SLisandro Dalcin ierr = VecGetArray(b,&bv);CHKERRQ(ierr); 31316d9e3a6SLisandro Dalcin ierr = VecGetArray(x,&xv);CHKERRQ(ierr); 31416d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,bv,sbv); 31516d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,xv,sxv); 31616d9e3a6SLisandro Dalcin 317fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat)); 318fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv)); 319fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv)); 32016d9e3a6SLisandro Dalcin 32116d9e3a6SLisandro Dalcin hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv); 32216d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 323e32f2f54SBarry Smith if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr); 32416d9e3a6SLisandro Dalcin if (hierr) hypre__global_error = 0; 32516d9e3a6SLisandro Dalcin 32616d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->b,sbv,bv); 32716d9e3a6SLisandro Dalcin HYPREReplacePointer(jac->x,sxv,xv); 32816d9e3a6SLisandro Dalcin ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr); 32916d9e3a6SLisandro Dalcin ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr); 33016d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 33116d9e3a6SLisandro Dalcin } 33216d9e3a6SLisandro Dalcin 333a669f990SJed Brown /* static array length */ 334a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0])) 335a669f990SJed Brown 33616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"","V","W"}; 3370f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"}; 33816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"}; 33965de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 34065de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[] = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi", 34165de4495SJed Brown "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi", 34265de4495SJed Brown "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination", 34365de4495SJed Brown "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */, 34465de4495SJed Brown "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"}; 3450f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[] = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i", 3460f1074feSSatish Balay "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"}; 34716d9e3a6SLisandro Dalcin #undef __FUNCT__ 34816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG" 3498c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc) 35016d9e3a6SLisandro Dalcin { 35116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 35216d9e3a6SLisandro Dalcin PetscErrorCode ierr; 3534ddd07fcSJed Brown PetscInt n,indx,level; 354ace3abfcSBarry Smith PetscBool flg, tmp_truth; 35516d9e3a6SLisandro Dalcin double tmpdbl, twodbl[2]; 35616d9e3a6SLisandro Dalcin 35716d9e3a6SLisandro Dalcin PetscFunctionBegin; 358e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr); 3594336a9eeSBarry Smith ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr); 36016d9e3a6SLisandro Dalcin if (flg) { 3614336a9eeSBarry Smith jac->cycletype = indx+1; 362fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype)); 36316d9e3a6SLisandro Dalcin } 36416d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr); 36516d9e3a6SLisandro Dalcin if (flg) { 366ce94432eSBarry Smith if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels); 367fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels)); 36816d9e3a6SLisandro Dalcin } 36916d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr); 37016d9e3a6SLisandro Dalcin if (flg) { 371ce94432eSBarry Smith if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter); 372fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 37316d9e3a6SLisandro Dalcin } 3740f1074feSSatish 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); 37516d9e3a6SLisandro Dalcin if (flg) { 37657622a8eSBarry 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); 377fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 37816d9e3a6SLisandro Dalcin } 37916d9e3a6SLisandro Dalcin 3800f1074feSSatish Balay ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr); 38116d9e3a6SLisandro Dalcin if (flg) { 38257622a8eSBarry 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); 383fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor)); 38416d9e3a6SLisandro Dalcin } 38516d9e3a6SLisandro Dalcin 3860f1074feSSatish 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); 3870f1074feSSatish Balay if (flg) { 38857622a8eSBarry 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); 389fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax)); 3900f1074feSSatish Balay } 3910f1074feSSatish Balay 3920f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr); 3930f1074feSSatish Balay if (flg) { 39457622a8eSBarry 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); 3950f1074feSSatish Balay 396fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl)); 3970f1074feSSatish Balay } 3980f1074feSSatish Balay 3990f1074feSSatish Balay 4000f1074feSSatish 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); 4010f1074feSSatish Balay if (flg) { 40257622a8eSBarry 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); 4030f1074feSSatish Balay 404fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths)); 4050f1074feSSatish Balay } 4060f1074feSSatish Balay 4070f1074feSSatish Balay 40816d9e3a6SLisandro Dalcin ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr); 40916d9e3a6SLisandro Dalcin if (flg) { 41057622a8eSBarry 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); 411fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold)); 41216d9e3a6SLisandro Dalcin } 41316d9e3a6SLisandro Dalcin ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr); 41416d9e3a6SLisandro Dalcin if (flg) { 41557622a8eSBarry 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); 41657622a8eSBarry 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); 417fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum)); 41816d9e3a6SLisandro Dalcin } 41916d9e3a6SLisandro Dalcin 42016d9e3a6SLisandro Dalcin /* Grid sweeps */ 4210f1074feSSatish 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); 42216d9e3a6SLisandro Dalcin if (flg) { 423fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx)); 42416d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 42516d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 4260f1074feSSatish Balay jac->gridsweeps[1] = indx; 4270f1074feSSatish Balay /*defaults coarse to 1 */ 4280f1074feSSatish Balay jac->gridsweeps[2] = 1; 42916d9e3a6SLisandro Dalcin } 4300f1074feSSatish Balay 4310f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr); 43216d9e3a6SLisandro Dalcin if (flg) { 433fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1)); 4340f1074feSSatish Balay jac->gridsweeps[0] = indx; 43516d9e3a6SLisandro Dalcin } 43616d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr); 43716d9e3a6SLisandro Dalcin if (flg) { 438fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2)); 4390f1074feSSatish Balay jac->gridsweeps[1] = indx; 44016d9e3a6SLisandro Dalcin } 4410f1074feSSatish Balay ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr); 44216d9e3a6SLisandro Dalcin if (flg) { 443fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3)); 4440f1074feSSatish Balay jac->gridsweeps[2] = indx; 44516d9e3a6SLisandro Dalcin } 44616d9e3a6SLisandro Dalcin 44716d9e3a6SLisandro Dalcin /* Relax type */ 448a669f990SJed 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); 44916d9e3a6SLisandro Dalcin if (flg) { 4500f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 451fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx)); 4520f1074feSSatish Balay /* by default, coarse type set to 9 */ 4530f1074feSSatish Balay jac->relaxtype[2] = 9; 4540f1074feSSatish Balay 45516d9e3a6SLisandro Dalcin } 456a669f990SJed 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); 45716d9e3a6SLisandro Dalcin if (flg) { 45816d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 459fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1)); 46016d9e3a6SLisandro Dalcin } 461a669f990SJed 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); 46216d9e3a6SLisandro Dalcin if (flg) { 4630f1074feSSatish Balay jac->relaxtype[1] = indx; 464fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2)); 46516d9e3a6SLisandro Dalcin } 466a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr); 46716d9e3a6SLisandro Dalcin if (flg) { 4680f1074feSSatish Balay jac->relaxtype[2] = indx; 469fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3)); 47016d9e3a6SLisandro Dalcin } 47116d9e3a6SLisandro Dalcin 47216d9e3a6SLisandro Dalcin /* Relaxation Weight */ 47316d9e3a6SLisandro 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); 47416d9e3a6SLisandro Dalcin if (flg) { 475fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl)); 47616d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 47716d9e3a6SLisandro Dalcin } 47816d9e3a6SLisandro Dalcin 47916d9e3a6SLisandro Dalcin n = 2; 48016d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 48116d9e3a6SLisandro 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); 48216d9e3a6SLisandro Dalcin if (flg) { 48316d9e3a6SLisandro Dalcin if (n == 2) { 48416d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 485fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx)); 486ce94432eSBarry 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); 48716d9e3a6SLisandro Dalcin } 48816d9e3a6SLisandro Dalcin 48916d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 49016d9e3a6SLisandro 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); 49116d9e3a6SLisandro Dalcin if (flg) { 492fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl)); 49316d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 49416d9e3a6SLisandro Dalcin } 49516d9e3a6SLisandro Dalcin 49616d9e3a6SLisandro Dalcin n = 2; 49716d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 49816d9e3a6SLisandro 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); 49916d9e3a6SLisandro Dalcin if (flg) { 50016d9e3a6SLisandro Dalcin if (n == 2) { 50116d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 502fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx)); 503ce94432eSBarry 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); 50416d9e3a6SLisandro Dalcin } 50516d9e3a6SLisandro Dalcin 50616d9e3a6SLisandro Dalcin /* the Relax Order */ 507acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 50816d9e3a6SLisandro Dalcin 5098afaa268SBarry Smith if (flg && tmp_truth) { 51016d9e3a6SLisandro Dalcin jac->relaxorder = 0; 511fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder)); 51216d9e3a6SLisandro Dalcin } 513a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr); 51416d9e3a6SLisandro Dalcin if (flg) { 51516d9e3a6SLisandro Dalcin jac->measuretype = indx; 516fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype)); 51716d9e3a6SLisandro Dalcin } 5180f1074feSSatish Balay /* update list length 3/07 */ 519a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr); 52016d9e3a6SLisandro Dalcin if (flg) { 52116d9e3a6SLisandro Dalcin jac->coarsentype = indx; 522fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype)); 52316d9e3a6SLisandro Dalcin } 5240f1074feSSatish Balay 5250f1074feSSatish Balay /* new 3/07 */ 526a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr); 5270f1074feSSatish Balay if (flg) { 5280f1074feSSatish Balay jac->interptype = indx; 529fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype)); 5300f1074feSSatish Balay } 5310f1074feSSatish Balay 532b96a4a96SBarry Smith ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr); 53316d9e3a6SLisandro Dalcin if (flg) { 534b96a4a96SBarry Smith level = 3; 5350298fd71SBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr); 5362fa5cd67SKarl Rupp 537b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 538fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level)); 5392ae77aedSBarry Smith } 5402ae77aedSBarry Smith 541b96a4a96SBarry Smith ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr); 5422ae77aedSBarry Smith if (flg) { 543b96a4a96SBarry Smith level = 3; 5440298fd71SBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr); 5452fa5cd67SKarl Rupp 546b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 547fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level)); 54816d9e3a6SLisandro Dalcin } 5498f87f92bSBarry Smith 5508afaa268SBarry Smith ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 5518f87f92bSBarry Smith if (flg && tmp_truth) { 5528f87f92bSBarry Smith jac->nodal_coarsen = 1; 553fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1)); 5548f87f92bSBarry Smith } 5558f87f92bSBarry Smith 556acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr); 5578f87f92bSBarry Smith if (flg && tmp_truth) { 5588f87f92bSBarry Smith PetscInt tmp_int; 5598f87f92bSBarry Smith ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr); 5608f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 561fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6)); 562fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1)); 563fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0)); 564fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels)); 5658f87f92bSBarry Smith } 5668f87f92bSBarry Smith 56716d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 56816d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 56916d9e3a6SLisandro Dalcin } 57016d9e3a6SLisandro Dalcin 57116d9e3a6SLisandro Dalcin #undef __FUNCT__ 57216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG" 573ace3abfcSBarry 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) 57416d9e3a6SLisandro Dalcin { 57516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 57616d9e3a6SLisandro Dalcin PetscErrorCode ierr; 5774ddd07fcSJed Brown PetscInt oits; 57816d9e3a6SLisandro Dalcin 57916d9e3a6SLisandro Dalcin PetscFunctionBegin; 580dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 581fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter)); 582fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol)); 58316d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 58416d9e3a6SLisandro Dalcin ierr = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr); 58516d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 5868b1f7689SBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits)); 5874d0a8057SBarry Smith *outits = oits; 5884d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 5894d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 590fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 591fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 59216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 59316d9e3a6SLisandro Dalcin } 59416d9e3a6SLisandro Dalcin 59516d9e3a6SLisandro Dalcin 59616d9e3a6SLisandro Dalcin #undef __FUNCT__ 59716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG" 59816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer) 59916d9e3a6SLisandro Dalcin { 60016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 60116d9e3a6SLisandro Dalcin PetscErrorCode ierr; 602ace3abfcSBarry Smith PetscBool iascii; 60316d9e3a6SLisandro Dalcin 60416d9e3a6SLisandro Dalcin PetscFunctionBegin; 605251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 60616d9e3a6SLisandro Dalcin if (iascii) { 60716d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr); 60816d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr); 60916d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr); 61016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr); 61157622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr); 61257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr); 61357622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr); 6140f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr); 6150f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr); 6160f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr); 6170f1074feSSatish Balay 61857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr); 61916d9e3a6SLisandro Dalcin 6200f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps down %d\n",jac->gridsweeps[0]);CHKERRQ(ierr); 6210f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps up %d\n",jac->gridsweeps[1]);CHKERRQ(ierr); 6220f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Sweeps on coarse %d\n",jac->gridsweeps[2]);CHKERRQ(ierr); 62316d9e3a6SLisandro Dalcin 6240f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax down %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr); 6250f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax up %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr); 6260f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax on coarse %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr); 62716d9e3a6SLisandro Dalcin 62857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Relax weight (all) %g\n",(double)jac->relaxweight);CHKERRQ(ierr); 62957622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr); 63016d9e3a6SLisandro Dalcin 63116d9e3a6SLisandro Dalcin if (jac->relaxorder) { 63216d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr); 63316d9e3a6SLisandro Dalcin } else { 63416d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr); 63516d9e3a6SLisandro Dalcin } 63616d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Measure type %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr); 63716d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Coarsen type %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr); 6380f1074feSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Interpolation type %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr); 6398f87f92bSBarry Smith if (jac->nodal_coarsen) { 6408f87f92bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr); 6418f87f92bSBarry Smith } 6428f87f92bSBarry Smith if (jac->nodal_relax) { 6438f87f92bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr); 6448f87f92bSBarry Smith } 64516d9e3a6SLisandro Dalcin } 64616d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 64716d9e3a6SLisandro Dalcin } 64816d9e3a6SLisandro Dalcin 64916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/ 65016d9e3a6SLisandro Dalcin #undef __FUNCT__ 65116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails" 6528c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc) 65316d9e3a6SLisandro Dalcin { 65416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 65516d9e3a6SLisandro Dalcin PetscErrorCode ierr; 6564ddd07fcSJed Brown PetscInt indx; 657ace3abfcSBarry Smith PetscBool flag; 65816d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"}; 65916d9e3a6SLisandro Dalcin 66016d9e3a6SLisandro Dalcin PetscFunctionBegin; 661e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr); 66216d9e3a6SLisandro Dalcin ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr); 66316d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr); 6642fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels)); 66516d9e3a6SLisandro Dalcin 66616d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr); 6672fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter)); 66816d9e3a6SLisandro Dalcin 66916d9e3a6SLisandro Dalcin ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr); 6702fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal)); 67116d9e3a6SLisandro Dalcin 672acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr); 6732fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging)); 67416d9e3a6SLisandro Dalcin 675acfcf0e5SJed Brown ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr); 6762fa5cd67SKarl Rupp if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse)); 67716d9e3a6SLisandro Dalcin 678a669f990SJed Brown ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr); 67916d9e3a6SLisandro Dalcin if (flag) { 68016d9e3a6SLisandro Dalcin jac->symt = indx; 681fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt)); 68216d9e3a6SLisandro Dalcin } 68316d9e3a6SLisandro Dalcin 68416d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 68516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 68616d9e3a6SLisandro Dalcin } 68716d9e3a6SLisandro Dalcin 68816d9e3a6SLisandro Dalcin #undef __FUNCT__ 68916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails" 69016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer) 69116d9e3a6SLisandro Dalcin { 69216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 69316d9e3a6SLisandro Dalcin PetscErrorCode ierr; 694ace3abfcSBarry Smith PetscBool iascii; 69516d9e3a6SLisandro Dalcin const char *symt = 0;; 69616d9e3a6SLisandro Dalcin 69716d9e3a6SLisandro Dalcin PetscFunctionBegin; 698251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 69916d9e3a6SLisandro Dalcin if (iascii) { 70016d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails preconditioning\n");CHKERRQ(ierr); 70116d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr); 70257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr); 70357622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr); 70457622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr); 705ace3abfcSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr); 706ace3abfcSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr); 7072fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 7082fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 7092fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 710ce94432eSBarry Smith else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt); 71116d9e3a6SLisandro Dalcin ierr = PetscViewerASCIIPrintf(viewer," HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr); 71216d9e3a6SLisandro Dalcin } 71316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 71416d9e3a6SLisandro Dalcin } 7154cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/ 7164cb006feSStefano Zampini #undef __FUNCT__ 7174cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS" 718*9fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc) 7194cb006feSStefano Zampini { 7204cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 7214cb006feSStefano Zampini PetscErrorCode ierr; 7224cb006feSStefano Zampini PetscInt n; 7234cb006feSStefano Zampini PetscBool flag,flag2,flag3,flag4; 7244cb006feSStefano Zampini 7254cb006feSStefano Zampini PetscFunctionBegin; 726*9fa463a7SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr); 7274cb006feSStefano Zampini ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->ams_print,&jac->ams_print,&flag);CHKERRQ(ierr); 7284cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print)); 7294cb006feSStefano 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); 7304cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter)); 7314cb006feSStefano 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); 7324cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type)); 7334cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->ams_tol,&jac->ams_tol,&flag);CHKERRQ(ierr); 7344cb006feSStefano Zampini if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol)); 7354cb006feSStefano 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); 7364cb006feSStefano 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); 7374cb006feSStefano 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); 7384cb006feSStefano Zampini ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->ams_omega,&jac->ams_omega,&flag4);CHKERRQ(ierr); 7394cb006feSStefano Zampini if (flag || flag2 || flag3 || flag4) { 7404cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type, 7414cb006feSStefano Zampini jac->ams_relax_times, 7424cb006feSStefano Zampini jac->ams_relax_weight, 7434cb006feSStefano Zampini jac->ams_omega)); 7444cb006feSStefano Zampini } 7454cb006feSStefano 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); 7464cb006feSStefano Zampini n = 5; 7474cb006feSStefano Zampini ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->ams_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr); 7484cb006feSStefano Zampini if (flag || flag2) { 7494cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0], /* AMG coarsen type */ 7504cb006feSStefano Zampini jac->ams_amg_alpha_opts[1], /* AMG agg_levels */ 7514cb006feSStefano Zampini jac->ams_amg_alpha_opts[2], /* AMG relax_type */ 7524cb006feSStefano Zampini jac->ams_amg_alpha_theta, 7534cb006feSStefano Zampini jac->ams_amg_alpha_opts[3], /* AMG interp_type */ 7544cb006feSStefano Zampini jac->ams_amg_alpha_opts[4])); /* AMG Pmax */ 7554cb006feSStefano Zampini } 7564cb006feSStefano 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); 7574cb006feSStefano Zampini n = 5; 7584cb006feSStefano 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); 7594cb006feSStefano Zampini if (flag || flag2) { 7604cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0], /* AMG coarsen type */ 7614cb006feSStefano Zampini jac->ams_amg_beta_opts[1], /* AMG agg_levels */ 7624cb006feSStefano Zampini jac->ams_amg_beta_opts[2], /* AMG relax_type */ 7634cb006feSStefano Zampini jac->ams_amg_beta_theta, 7644cb006feSStefano Zampini jac->ams_amg_beta_opts[3], /* AMG interp_type */ 7654cb006feSStefano Zampini jac->ams_amg_beta_opts[4])); /* AMG Pmax */ 7664cb006feSStefano Zampini } 7674cb006feSStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 7684cb006feSStefano Zampini PetscFunctionReturn(0); 7694cb006feSStefano Zampini } 7704cb006feSStefano Zampini 7714cb006feSStefano Zampini #undef __FUNCT__ 7724cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS" 7734cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer) 7744cb006feSStefano Zampini { 7754cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 7764cb006feSStefano Zampini PetscErrorCode ierr; 7774cb006feSStefano Zampini PetscBool iascii; 7784cb006feSStefano Zampini 7794cb006feSStefano Zampini PetscFunctionBegin; 7804cb006feSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 7814cb006feSStefano Zampini if (iascii) { 7824cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS preconditioning\n");CHKERRQ(ierr); 7834cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace iterations per application %d\n",jac->ams_max_iter);CHKERRQ(ierr); 7844cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr); 7854cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: subspace iteration tolerance %g\n",jac->ams_tol);CHKERRQ(ierr); 7864cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother type %d\n",jac->ams_relax_type);CHKERRQ(ierr); 7874cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: number of smoothing steps %d\n",jac->ams_relax_times);CHKERRQ(ierr); 7884cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother weight %g\n",jac->ams_relax_weight);CHKERRQ(ierr); 7894cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: smoother omega %g\n",jac->ams_omega);CHKERRQ(ierr); 7904cb006feSStefano Zampini if (jac->alpha_Poisson) { 7914cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr); 7924cb006feSStefano Zampini } else { 7934cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr); 7944cb006feSStefano Zampini } 7954cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG coarsening type %d\n",jac->ams_amg_alpha_opts[0]);CHKERRQ(ierr); 7964cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_alpha_opts[1]);CHKERRQ(ierr); 7974cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG relaxation type %d\n",jac->ams_amg_alpha_opts[2]);CHKERRQ(ierr); 7984cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG interpolation type %d\n",jac->ams_amg_alpha_opts[3]);CHKERRQ(ierr); 7994cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_alpha_opts[4]);CHKERRQ(ierr); 8004cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG strength threshold %g\n",jac->ams_amg_alpha_theta);CHKERRQ(ierr); 8014cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 8024cb006feSStefano Zampini if (jac->beta_Poisson) { 8034cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr); 8044cb006feSStefano Zampini } else { 8054cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr); 8064cb006feSStefano Zampini } 8074cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG coarsening type %d\n",jac->ams_amg_beta_opts[0]);CHKERRQ(ierr); 8084cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_beta_opts[1]);CHKERRQ(ierr); 8094cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG relaxation type %d\n",jac->ams_amg_beta_opts[2]);CHKERRQ(ierr); 8104cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG interpolation type %d\n",jac->ams_amg_beta_opts[3]);CHKERRQ(ierr); 8114cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_beta_opts[4]);CHKERRQ(ierr); 8124cb006feSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," HYPRE AMS: boomerAMG strength threshold %g\n",jac->ams_amg_beta_theta);CHKERRQ(ierr); 8134cb006feSStefano Zampini } 8144cb006feSStefano Zampini } 8154cb006feSStefano Zampini PetscFunctionReturn(0); 8164cb006feSStefano Zampini } 8174cb006feSStefano Zampini 8184cb006feSStefano Zampini #undef __FUNCT__ 8194cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE_AMS" 8204cb006feSStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE_AMS(PC pc, Mat G) 8214cb006feSStefano Zampini { 8224cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 8234cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_G; 8244cb006feSStefano Zampini PetscErrorCode ierr; 8254cb006feSStefano Zampini 8264cb006feSStefano Zampini PetscFunctionBegin; 8274cb006feSStefano Zampini /* throw away any discrete gradient if already set */ 8284cb006feSStefano Zampini if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); 8294cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr); 8304cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr); 8314cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G))); 8324cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr_G)); 8334cb006feSStefano Zampini PetscFunctionReturn(0); 8344cb006feSStefano Zampini } 8354cb006feSStefano Zampini 8364cb006feSStefano Zampini #undef __FUNCT__ 8374cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient" 8384cb006feSStefano Zampini /*@ 8394cb006feSStefano Zampini PCHYPRESetDiscreteGradient - Set discrete gradient matrix 8404cb006feSStefano Zampini 8414cb006feSStefano Zampini Collective on PC 8424cb006feSStefano Zampini 8434cb006feSStefano Zampini Input Parameters: 8444cb006feSStefano Zampini + pc - the preconditioning context 8454cb006feSStefano Zampini - G - the discrete gradient 8464cb006feSStefano Zampini 8474cb006feSStefano Zampini Level: intermediate 8484cb006feSStefano Zampini 8494cb006feSStefano 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 8504cb006feSStefano 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 8514cb006feSStefano Zampini 8524cb006feSStefano Zampini .seealso: 8534cb006feSStefano Zampini @*/ 8544cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 8554cb006feSStefano Zampini { 8564cb006feSStefano Zampini PetscErrorCode ierr; 8574cb006feSStefano Zampini 8584cb006feSStefano Zampini PetscFunctionBegin; 8594cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8604cb006feSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 8614cb006feSStefano Zampini PetscCheckSameComm(pc,1,G,2); 8624cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr); 8634cb006feSStefano Zampini PetscFunctionReturn(0); 8644cb006feSStefano Zampini } 8654cb006feSStefano Zampini 8664cb006feSStefano Zampini #undef __FUNCT__ 8674cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS" 8684cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A) 8694cb006feSStefano Zampini { 8704cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 8714cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_alpha_Poisson; 8724cb006feSStefano Zampini PetscErrorCode ierr; 8734cb006feSStefano Zampini 8744cb006feSStefano Zampini PetscFunctionBegin; 8754cb006feSStefano Zampini /* throw away any matrix if already set */ 8764cb006feSStefano Zampini if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); 8774cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr); 8784cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr); 8794cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson))); 8804cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson)); 8814cb006feSStefano Zampini PetscFunctionReturn(0); 8824cb006feSStefano Zampini } 8834cb006feSStefano Zampini 8844cb006feSStefano Zampini #undef __FUNCT__ 8854cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix" 8864cb006feSStefano Zampini /*@ 8874cb006feSStefano Zampini PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix 8884cb006feSStefano Zampini 8894cb006feSStefano Zampini Collective on PC 8904cb006feSStefano Zampini 8914cb006feSStefano Zampini Input Parameters: 8924cb006feSStefano Zampini + pc - the preconditioning context 8934cb006feSStefano Zampini - A - the matrix 8944cb006feSStefano Zampini 8954cb006feSStefano Zampini Level: intermediate 8964cb006feSStefano Zampini 8974cb006feSStefano Zampini Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 8984cb006feSStefano Zampini 8994cb006feSStefano Zampini .seealso: 9004cb006feSStefano Zampini @*/ 9014cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 9024cb006feSStefano Zampini { 9034cb006feSStefano Zampini PetscErrorCode ierr; 9044cb006feSStefano Zampini 9054cb006feSStefano Zampini PetscFunctionBegin; 9064cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9074cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 9084cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 9094cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr); 9104cb006feSStefano Zampini PetscFunctionReturn(0); 9114cb006feSStefano Zampini } 9124cb006feSStefano Zampini 9134cb006feSStefano Zampini #undef __FUNCT__ 9144cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS" 9154cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A) 9164cb006feSStefano Zampini { 9174cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 9184cb006feSStefano Zampini HYPRE_ParCSRMatrix parcsr_beta_Poisson; 9194cb006feSStefano Zampini PetscErrorCode ierr; 9204cb006feSStefano Zampini 9214cb006feSStefano Zampini PetscFunctionBegin; 9224cb006feSStefano Zampini if (!A) { 9234cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 9244cb006feSStefano Zampini PetscFunctionReturn(0); 9254cb006feSStefano Zampini } 9264cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 9274cb006feSStefano Zampini /* throw away any matrix if already set */ 9284cb006feSStefano Zampini if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); 9294cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr); 9304cb006feSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr); 9314cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson))); 9324cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson)); 9334cb006feSStefano Zampini PetscFunctionReturn(0); 9344cb006feSStefano Zampini } 9354cb006feSStefano Zampini 9364cb006feSStefano Zampini #undef __FUNCT__ 9374cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix" 9384cb006feSStefano Zampini /*@ 9394cb006feSStefano Zampini PCHYPRESetBetaPoissonMatrix - Set Poisson matrix 9404cb006feSStefano Zampini 9414cb006feSStefano Zampini Collective on PC 9424cb006feSStefano Zampini 9434cb006feSStefano Zampini Input Parameters: 9444cb006feSStefano Zampini + pc - the preconditioning context 9454cb006feSStefano Zampini - A - the matrix 9464cb006feSStefano Zampini 9474cb006feSStefano Zampini Level: intermediate 9484cb006feSStefano Zampini 9494cb006feSStefano Zampini Notes: A should be obtained by discretizing the Poisson problem with linear finite elements. 9504cb006feSStefano Zampini Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL. 9514cb006feSStefano Zampini 9524cb006feSStefano Zampini .seealso: 9534cb006feSStefano Zampini @*/ 9544cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 9554cb006feSStefano Zampini { 9564cb006feSStefano Zampini PetscErrorCode ierr; 9574cb006feSStefano Zampini 9584cb006feSStefano Zampini PetscFunctionBegin; 9594cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9604cb006feSStefano Zampini if (A) { 9614cb006feSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,2); 9624cb006feSStefano Zampini PetscCheckSameComm(pc,1,A,2); 9634cb006feSStefano Zampini } 9644cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr); 9654cb006feSStefano Zampini PetscFunctionReturn(0); 9664cb006feSStefano Zampini } 9674cb006feSStefano Zampini 9684cb006feSStefano Zampini #undef __FUNCT__ 9694cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS" 9704cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo) 9714cb006feSStefano Zampini { 9724cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 9734cb006feSStefano Zampini HYPRE_ParVector par_ozz,par_zoz,par_zzo; 97412ddd1b6SStefano Zampini PetscInt dim; 9754cb006feSStefano Zampini PetscErrorCode ierr; 9764cb006feSStefano Zampini 9774cb006feSStefano Zampini PetscFunctionBegin; 9784cb006feSStefano Zampini /* throw away any vector if already set */ 9794cb006feSStefano Zampini if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); 9804cb006feSStefano Zampini if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); 9814cb006feSStefano Zampini if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); 9824cb006feSStefano Zampini jac->constants[0] = NULL; 9834cb006feSStefano Zampini jac->constants[1] = NULL; 9844cb006feSStefano Zampini jac->constants[2] = NULL; 9854cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr); 9864cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr); 9874cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz))); 9884cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr); 9894cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr); 9904cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz))); 99112ddd1b6SStefano Zampini dim = 2; 9924cb006feSStefano Zampini if (zzo) { 9934cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr); 9944cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr); 9954cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo))); 99612ddd1b6SStefano Zampini dim++; 9974cb006feSStefano Zampini } 9984cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo)); 99912ddd1b6SStefano Zampini PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim)); 10004cb006feSStefano Zampini PetscFunctionReturn(0); 10014cb006feSStefano Zampini } 10024cb006feSStefano Zampini 10034cb006feSStefano Zampini #undef __FUNCT__ 10044cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors" 10054cb006feSStefano Zampini /*@ 10064cb006feSStefano Zampini PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis 10074cb006feSStefano Zampini 10084cb006feSStefano Zampini Collective on PC 10094cb006feSStefano Zampini 10104cb006feSStefano Zampini Input Parameters: 10114cb006feSStefano Zampini + pc - the preconditioning context 10124cb006feSStefano Zampini - ozz - vector representing (1,0,0) (or (1,0) in 2D) 10134cb006feSStefano Zampini - zoz - vector representing (0,1,0) (or (0,1) in 2D) 10144cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 10154cb006feSStefano Zampini 10164cb006feSStefano Zampini Level: intermediate 10174cb006feSStefano Zampini 10184cb006feSStefano Zampini Notes: 10194cb006feSStefano Zampini 10204cb006feSStefano Zampini .seealso: 10214cb006feSStefano Zampini @*/ 10224cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 10234cb006feSStefano Zampini { 10244cb006feSStefano Zampini PetscErrorCode ierr; 10254cb006feSStefano Zampini 10264cb006feSStefano Zampini PetscFunctionBegin; 10274cb006feSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 10284cb006feSStefano Zampini PetscValidHeaderSpecific(ozz,VEC_CLASSID,2); 10294cb006feSStefano Zampini PetscValidHeaderSpecific(zoz,VEC_CLASSID,3); 10304cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4); 10314cb006feSStefano Zampini PetscCheckSameComm(pc,1,ozz,2); 10324cb006feSStefano Zampini PetscCheckSameComm(pc,1,zoz,3); 10334cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc,1,zzo,4); 10344cb006feSStefano Zampini ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr); 10354cb006feSStefano Zampini PetscFunctionReturn(0); 10364cb006feSStefano Zampini } 10374cb006feSStefano Zampini 10384cb006feSStefano Zampini #undef __FUNCT__ 10394cb006feSStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE_AMS" 10404cb006feSStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE_AMS(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 10414cb006feSStefano Zampini { 10424cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE*)pc->data; 10434cb006feSStefano Zampini Vec tv; 10444cb006feSStefano Zampini HYPRE_ParVector par_coords[3]; 10454cb006feSStefano Zampini PetscInt i; 10464cb006feSStefano Zampini PetscErrorCode ierr; 10474cb006feSStefano Zampini 10484cb006feSStefano Zampini PetscFunctionBegin; 10494cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 10504cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); 10514cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); 10524cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); 10534cb006feSStefano Zampini /* set problem's dimension */ 10544cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim)); 10554cb006feSStefano Zampini /* compute IJ vector for coordinates */ 10564cb006feSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr); 10574cb006feSStefano Zampini ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr); 10584cb006feSStefano Zampini ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr); 10594cb006feSStefano Zampini for (i=0;i<dim;i++) { 10604cb006feSStefano Zampini PetscScalar *array; 10614cb006feSStefano Zampini PetscInt j; 10624cb006feSStefano Zampini 10634cb006feSStefano Zampini ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr); 10644cb006feSStefano Zampini ierr = VecGetArray(tv,&array);CHKERRQ(ierr); 10654cb006feSStefano Zampini for (j=0;j<nloc;j++) { 10664cb006feSStefano Zampini array[j] = coords[j*dim+i]; 10674cb006feSStefano Zampini } 10684cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array)); 10694cb006feSStefano Zampini PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i])); 10704cb006feSStefano Zampini ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr); 10714cb006feSStefano Zampini } 10724cb006feSStefano Zampini ierr = VecDestroy(&tv);CHKERRQ(ierr); 10734cb006feSStefano Zampini /* pass parCSR vectors to AMS solver */ 10744cb006feSStefano Zampini par_coords[0] = NULL; 10754cb006feSStefano Zampini par_coords[1] = NULL; 10764cb006feSStefano Zampini par_coords[2] = NULL; 10774cb006feSStefano Zampini if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0]))); 10784cb006feSStefano Zampini if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1]))); 10794cb006feSStefano Zampini if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2]))); 10804cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,par_coords[0],par_coords[1],par_coords[2])); 10814cb006feSStefano Zampini PetscFunctionReturn(0); 10824cb006feSStefano Zampini } 10834cb006feSStefano Zampini 108416d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/ 108516d9e3a6SLisandro Dalcin 108616d9e3a6SLisandro Dalcin #undef __FUNCT__ 108716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE" 1088f7a08781SBarry Smith static PetscErrorCode PCHYPREGetType_HYPRE(PC pc,const char *name[]) 108916d9e3a6SLisandro Dalcin { 109016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 109116d9e3a6SLisandro Dalcin 109216d9e3a6SLisandro Dalcin PetscFunctionBegin; 109316d9e3a6SLisandro Dalcin *name = jac->hypre_type; 109416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 109516d9e3a6SLisandro Dalcin } 109616d9e3a6SLisandro Dalcin 109716d9e3a6SLisandro Dalcin #undef __FUNCT__ 109816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE" 1099f7a08781SBarry Smith static PetscErrorCode PCHYPRESetType_HYPRE(PC pc,const char name[]) 110016d9e3a6SLisandro Dalcin { 110116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE*)pc->data; 110216d9e3a6SLisandro Dalcin PetscErrorCode ierr; 1103ace3abfcSBarry Smith PetscBool flag; 110416d9e3a6SLisandro Dalcin 110516d9e3a6SLisandro Dalcin PetscFunctionBegin; 110616d9e3a6SLisandro Dalcin if (jac->hypre_type) { 110716d9e3a6SLisandro Dalcin ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr); 1108ce94432eSBarry Smith if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set"); 110916d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 111016d9e3a6SLisandro Dalcin } else { 111116d9e3a6SLisandro Dalcin ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr); 111216d9e3a6SLisandro Dalcin } 111316d9e3a6SLisandro Dalcin 111416d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 111516d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 111616d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 111716d9e3a6SLisandro Dalcin 111816d9e3a6SLisandro Dalcin ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr); 111916d9e3a6SLisandro Dalcin if (flag) { 1120fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver)); 112116d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 112216d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 112316d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 112416d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 112516d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 112616d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 112716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 112816d9e3a6SLisandro Dalcin } 112916d9e3a6SLisandro Dalcin ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr); 113016d9e3a6SLisandro Dalcin if (flag) { 1131fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver)); 113216d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 113316d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 113416d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 113516d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 113616d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 113716d9e3a6SLisandro Dalcin /* initialize */ 113816d9e3a6SLisandro Dalcin jac->nlevels = 1; 113916d9e3a6SLisandro Dalcin jac->threshhold = .1; 114016d9e3a6SLisandro Dalcin jac->filter = .1; 114116d9e3a6SLisandro Dalcin jac->loadbal = 0; 11422fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE; 11432fa5cd67SKarl Rupp else jac->logging = (int) PETSC_FALSE; 11442fa5cd67SKarl Rupp 114516d9e3a6SLisandro Dalcin jac->ruse = (int) PETSC_FALSE; 114616d9e3a6SLisandro Dalcin jac->symt = 0; 1147fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels)); 1148fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter)); 1149fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal)); 1150fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging)); 1151fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse)); 1152fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt)); 115316d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 115416d9e3a6SLisandro Dalcin } 115516d9e3a6SLisandro Dalcin ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr); 115616d9e3a6SLisandro Dalcin if (flag) { 115716d9e3a6SLisandro Dalcin ierr = HYPRE_BoomerAMGCreate(&jac->hsolver); 115816d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 115916d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 116016d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 116116d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 116216d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 116316d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 116416d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 116516d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 116616d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 116716d9e3a6SLisandro Dalcin jac->cycletype = 1; 116816d9e3a6SLisandro Dalcin jac->maxlevels = 25; 116916d9e3a6SLisandro Dalcin jac->maxiter = 1; 11708f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 117116d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 117216d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 117316d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 117416d9e3a6SLisandro Dalcin jac->coarsentype = 6; 117516d9e3a6SLisandro Dalcin jac->measuretype = 0; 11760f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 11778f87f92bSBarry Smith jac->relaxtype[0] = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */ 11780f1074feSSatish Balay jac->relaxtype[2] = 9; /*G.E. */ 117916d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 118016d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 118116d9e3a6SLisandro Dalcin jac->relaxorder = 1; 11820f1074feSSatish Balay jac->interptype = 0; 11830f1074feSSatish Balay jac->agg_nl = 0; 11840f1074feSSatish Balay jac->pmax = 0; 11850f1074feSSatish Balay jac->truncfactor = 0.0; 11860f1074feSSatish Balay jac->agg_num_paths = 1; 11878f87f92bSBarry Smith 11888f87f92bSBarry Smith jac->nodal_coarsen = 0; 11898f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 11908f87f92bSBarry Smith jac->nodal_relax_levels = 1; 1191fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype)); 1192fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels)); 1193fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter)); 1194fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol)); 1195fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor)); 1196fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold)); 1197fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum)); 1198fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype)); 1199fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype)); 1200fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder)); 1201fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype)); 1202fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl)); 1203fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax)); 1204fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths)); 1205fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0])); /*defaults coarse to 9*/ 1206fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */ 120716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 120816d9e3a6SLisandro Dalcin } 12094cb006feSStefano Zampini ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr); 12104cb006feSStefano Zampini if (flag) { 12114cb006feSStefano Zampini ierr = HYPRE_AMSCreate(&jac->hsolver); 12124cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 12134cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 12144cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 12154cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 12164cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 12174cb006feSStefano Zampini jac->coords[0] = NULL; 12184cb006feSStefano Zampini jac->coords[1] = NULL; 12194cb006feSStefano Zampini jac->coords[2] = NULL; 12204cb006feSStefano Zampini jac->G = NULL; 12214cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 12224cb006feSStefano Zampini jac->ams_print = 0; 12234cb006feSStefano Zampini jac->ams_max_iter = 1; /* used as a preconditioner */ 12244cb006feSStefano Zampini jac->ams_cycle_type = 13; 12254cb006feSStefano Zampini jac->ams_tol = 0.; /* used as a preconditioner */ 12264cb006feSStefano Zampini /* Smoothing options */ 12274cb006feSStefano Zampini jac->ams_relax_type = 2; 12284cb006feSStefano Zampini jac->ams_relax_times = 1; 12294cb006feSStefano Zampini jac->ams_relax_weight = 1.0; 12304cb006feSStefano Zampini jac->ams_omega = 1.0; 12314cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 12324cb006feSStefano Zampini jac->ams_amg_alpha_opts[0] = 10; 12334cb006feSStefano Zampini jac->ams_amg_alpha_opts[1] = 1; 12344cb006feSStefano Zampini jac->ams_amg_alpha_opts[2] = 8; 12354cb006feSStefano Zampini jac->ams_amg_alpha_opts[3] = 6; 12364cb006feSStefano Zampini jac->ams_amg_alpha_opts[4] = 4; 12374cb006feSStefano Zampini jac->ams_amg_alpha_theta = 0.25; 12384cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 12394cb006feSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 12404cb006feSStefano Zampini jac->ams_amg_beta_opts[0] = 10; 12414cb006feSStefano Zampini jac->ams_amg_beta_opts[1] = 1; 12424cb006feSStefano Zampini jac->ams_amg_beta_opts[2] = 8; 12434cb006feSStefano Zampini jac->ams_amg_beta_opts[3] = 6; 12444cb006feSStefano Zampini jac->ams_amg_beta_opts[4] = 4; 12454cb006feSStefano Zampini jac->ams_amg_beta_theta = 0.25; 12464cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print)); 12474cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter)); 12484cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type)); 12494cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol)); 12504cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type, 12514cb006feSStefano Zampini jac->ams_relax_times, 12524cb006feSStefano Zampini jac->ams_relax_weight, 12534cb006feSStefano Zampini jac->ams_omega)); 12544cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0], /* AMG coarsen type */ 12554cb006feSStefano Zampini jac->ams_amg_alpha_opts[1], /* AMG agg_levels */ 12564cb006feSStefano Zampini jac->ams_amg_alpha_opts[2], /* AMG relax_type */ 12574cb006feSStefano Zampini jac->ams_amg_alpha_theta, 12584cb006feSStefano Zampini jac->ams_amg_alpha_opts[3], /* AMG interp_type */ 12594cb006feSStefano Zampini jac->ams_amg_alpha_opts[4])); /* AMG Pmax */ 12604cb006feSStefano Zampini PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0], /* AMG coarsen type */ 12614cb006feSStefano Zampini jac->ams_amg_beta_opts[1], /* AMG agg_levels */ 12624cb006feSStefano Zampini jac->ams_amg_beta_opts[2], /* AMG relax_type */ 12634cb006feSStefano Zampini jac->ams_amg_beta_theta, 12644cb006feSStefano Zampini jac->ams_amg_beta_opts[3], /* AMG interp_type */ 12654cb006feSStefano Zampini jac->ams_amg_beta_opts[4])); /* AMG Pmax */ 12664cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE_AMS);CHKERRQ(ierr); 12674cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE_AMS);CHKERRQ(ierr); 12684cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr); 12694cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr); 12704cb006feSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr); 12714cb006feSStefano Zampini PetscFunctionReturn(0); 12724cb006feSStefano Zampini } 1273503cfb0cSBarry Smith ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr); 12742fa5cd67SKarl Rupp 12750298fd71SBarry Smith jac->hypre_type = NULL; 127633263987SBarry Smith SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name); 127716d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 127816d9e3a6SLisandro Dalcin } 127916d9e3a6SLisandro Dalcin 128016d9e3a6SLisandro Dalcin /* 128116d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 128216d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 128316d9e3a6SLisandro Dalcin */ 128416d9e3a6SLisandro Dalcin #undef __FUNCT__ 128516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE" 12868c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc) 128716d9e3a6SLisandro Dalcin { 128816d9e3a6SLisandro Dalcin PetscErrorCode ierr; 12894ddd07fcSJed Brown PetscInt indx; 129033263987SBarry Smith const char *type[] = {"pilut","parasails","boomeramg","ams"}; 1291ace3abfcSBarry Smith PetscBool flg; 129216d9e3a6SLisandro Dalcin 129316d9e3a6SLisandro Dalcin PetscFunctionBegin; 1294*9fa463a7SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr); 12954cb006feSStefano Zampini ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,5,"boomeramg",&indx,&flg);CHKERRQ(ierr); 129616d9e3a6SLisandro Dalcin if (flg) { 129716d9e3a6SLisandro Dalcin ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr); 129802a17cd4SBarry Smith } else { 129902a17cd4SBarry Smith ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr); 130016d9e3a6SLisandro Dalcin } 130116d9e3a6SLisandro Dalcin if (pc->ops->setfromoptions) { 13023931853cSBarry Smith ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr); 130316d9e3a6SLisandro Dalcin } 130416d9e3a6SLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 130516d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 130616d9e3a6SLisandro Dalcin } 130716d9e3a6SLisandro Dalcin 130816d9e3a6SLisandro Dalcin #undef __FUNCT__ 130916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType" 131016d9e3a6SLisandro Dalcin /*@C 131116d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 131216d9e3a6SLisandro Dalcin 131316d9e3a6SLisandro Dalcin Input Parameters: 131416d9e3a6SLisandro Dalcin + pc - the preconditioner context 131533263987SBarry Smith - name - either pilut, parasails, boomeramg, ams 131616d9e3a6SLisandro Dalcin 131716d9e3a6SLisandro Dalcin Options Database Keys: 131833263987SBarry Smith -pc_hypre_type - One of pilut, parasails, boomeramg, ams 131916d9e3a6SLisandro Dalcin 132016d9e3a6SLisandro Dalcin Level: intermediate 132116d9e3a6SLisandro Dalcin 132216d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 132316d9e3a6SLisandro Dalcin PCHYPRE 132416d9e3a6SLisandro Dalcin 132516d9e3a6SLisandro Dalcin @*/ 13267087cfbeSBarry Smith PetscErrorCode PCHYPRESetType(PC pc,const char name[]) 132716d9e3a6SLisandro Dalcin { 13284ac538c5SBarry Smith PetscErrorCode ierr; 132916d9e3a6SLisandro Dalcin 133016d9e3a6SLisandro Dalcin PetscFunctionBegin; 13310700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 133216d9e3a6SLisandro Dalcin PetscValidCharPointer(name,2); 13334ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr); 133416d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 133516d9e3a6SLisandro Dalcin } 133616d9e3a6SLisandro Dalcin 133716d9e3a6SLisandro Dalcin #undef __FUNCT__ 133816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType" 133916d9e3a6SLisandro Dalcin /*@C 134016d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 134116d9e3a6SLisandro Dalcin 134216d9e3a6SLisandro Dalcin Input Parameter: 134316d9e3a6SLisandro Dalcin . pc - the preconditioner context 134416d9e3a6SLisandro Dalcin 134516d9e3a6SLisandro Dalcin Output Parameter: 134633263987SBarry Smith . name - either pilut, parasails, boomeramg, ams 134716d9e3a6SLisandro Dalcin 134816d9e3a6SLisandro Dalcin Level: intermediate 134916d9e3a6SLisandro Dalcin 135016d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC, 135116d9e3a6SLisandro Dalcin PCHYPRE 135216d9e3a6SLisandro Dalcin 135316d9e3a6SLisandro Dalcin @*/ 13547087cfbeSBarry Smith PetscErrorCode PCHYPREGetType(PC pc,const char *name[]) 135516d9e3a6SLisandro Dalcin { 13564ac538c5SBarry Smith PetscErrorCode ierr; 135716d9e3a6SLisandro Dalcin 135816d9e3a6SLisandro Dalcin PetscFunctionBegin; 13590700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 136016d9e3a6SLisandro Dalcin PetscValidPointer(name,2); 13614ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr); 136216d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 136316d9e3a6SLisandro Dalcin } 136416d9e3a6SLisandro Dalcin 136516d9e3a6SLisandro Dalcin /*MC 136616d9e3a6SLisandro Dalcin PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre 136716d9e3a6SLisandro Dalcin 136816d9e3a6SLisandro Dalcin Options Database Keys: 136933263987SBarry Smith + -pc_hypre_type - One of pilut, parasails, boomeramg, ams 137016d9e3a6SLisandro Dalcin - Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX 137116d9e3a6SLisandro Dalcin preconditioner 137216d9e3a6SLisandro Dalcin 137316d9e3a6SLisandro Dalcin Level: intermediate 137416d9e3a6SLisandro Dalcin 137516d9e3a6SLisandro Dalcin Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()), 137616d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 137716d9e3a6SLisandro Dalcin or with PetscOptionsSetValue(), there are no functions to set them) 137816d9e3a6SLisandro Dalcin 137916d9e3a6SLisandro Dalcin The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations 13800f1074feSSatish Balay (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if 13810f1074feSSatish Balay -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner 13820f1074feSSatish Balay (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of 13838f87f92bSBarry Smith iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations 13840f1074feSSatish Balay and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10 13850f1074feSSatish Balay then AT MOST twenty V-cycles of boomeramg will be called. 138616d9e3a6SLisandro Dalcin 13870f1074feSSatish Balay Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation 13880f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 13890f1074feSSatish Balay Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi. 139016d9e3a6SLisandro Dalcin If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly 139116d9e3a6SLisandro Dalcin and use -ksp_max_it to control the number of V-cycles. 139216d9e3a6SLisandro Dalcin (see the PETSc FAQ.html at the PETSc website under the Documentation tab). 139316d9e3a6SLisandro Dalcin 139416d9e3a6SLisandro Dalcin 2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option 139516d9e3a6SLisandro Dalcin -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L. 139616d9e3a6SLisandro Dalcin 13979e5bc791SBarry Smith See PCPFMG for access to the hypre Struct PFMG solver 13989e5bc791SBarry Smith 139916d9e3a6SLisandro Dalcin .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 14009e5bc791SBarry Smith PCHYPRESetType(), PCPFMG 140116d9e3a6SLisandro Dalcin 140216d9e3a6SLisandro Dalcin M*/ 140316d9e3a6SLisandro Dalcin 140416d9e3a6SLisandro Dalcin #undef __FUNCT__ 140516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE" 14068cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 140716d9e3a6SLisandro Dalcin { 140816d9e3a6SLisandro Dalcin PC_HYPRE *jac; 140916d9e3a6SLisandro Dalcin PetscErrorCode ierr; 141016d9e3a6SLisandro Dalcin 141116d9e3a6SLisandro Dalcin PetscFunctionBegin; 1412b00a9115SJed Brown ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 14132fa5cd67SKarl Rupp 141416d9e3a6SLisandro Dalcin pc->data = jac; 141516d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 141616d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 141716d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 141816d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 141916d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 14200298fd71SBarry Smith jac->hypre_type = NULL; 14214cb006feSStefano Zampini jac->coords[0] = NULL; 14224cb006feSStefano Zampini jac->coords[1] = NULL; 14234cb006feSStefano Zampini jac->coords[2] = NULL; 14244cb006feSStefano Zampini jac->constants[0] = NULL; 14254cb006feSStefano Zampini jac->constants[1] = NULL; 14264cb006feSStefano Zampini jac->constants[2] = NULL; 142716d9e3a6SLisandro Dalcin /* duplicate communicator for hypre */ 1428ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr); 1429bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr); 1430bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr); 143116d9e3a6SLisandro Dalcin PetscFunctionReturn(0); 143216d9e3a6SLisandro Dalcin } 1433ebc551c0SBarry Smith 1434f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/ 1435f91d8e95SBarry Smith 1436b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */ 1437b45d2f2cSJed Brown #include <petsc-private/matimpl.h> 1438ebc551c0SBarry Smith 1439ebc551c0SBarry Smith typedef struct { 144068326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 1441f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 14429e5bc791SBarry Smith 14439e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 14444ddd07fcSJed Brown PetscInt its; 14459e5bc791SBarry Smith double tol; 14464ddd07fcSJed Brown PetscInt relax_type; 14474ddd07fcSJed Brown PetscInt rap_type; 14484ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 14494ddd07fcSJed Brown PetscInt max_levels; 1450ebc551c0SBarry Smith } PC_PFMG; 1451ebc551c0SBarry Smith 1452ebc551c0SBarry Smith #undef __FUNCT__ 1453ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG" 1454ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc) 1455ebc551c0SBarry Smith { 1456ebc551c0SBarry Smith PetscErrorCode ierr; 1457f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1458ebc551c0SBarry Smith 1459ebc551c0SBarry Smith PetscFunctionBegin; 14602fa5cd67SKarl Rupp if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver)); 1461f91d8e95SBarry Smith ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr); 1462c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 1463ebc551c0SBarry Smith PetscFunctionReturn(0); 1464ebc551c0SBarry Smith } 1465ebc551c0SBarry Smith 14669e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"}; 14679e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"}; 14689e5bc791SBarry Smith 1469ebc551c0SBarry Smith #undef __FUNCT__ 1470ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG" 1471ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer) 1472ebc551c0SBarry Smith { 1473ebc551c0SBarry Smith PetscErrorCode ierr; 1474ace3abfcSBarry Smith PetscBool iascii; 1475f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1476ebc551c0SBarry Smith 1477ebc551c0SBarry Smith PetscFunctionBegin; 1478251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 14799e5bc791SBarry Smith if (iascii) { 14809e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG preconditioning\n");CHKERRQ(ierr); 14819e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr); 14829e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr); 14839e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr); 14849e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr); 14859e5bc791SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr); 14863b46a515SGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr); 14879e5bc791SBarry Smith } 1488ebc551c0SBarry Smith PetscFunctionReturn(0); 1489ebc551c0SBarry Smith } 1490ebc551c0SBarry Smith 14919e5bc791SBarry Smith 1492ebc551c0SBarry Smith #undef __FUNCT__ 1493ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG" 14948c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc) 1495ebc551c0SBarry Smith { 1496ebc551c0SBarry Smith PetscErrorCode ierr; 1497f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1498ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1499ebc551c0SBarry Smith 1500ebc551c0SBarry Smith PetscFunctionBegin; 1501e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr); 15020298fd71SBarry Smith ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr); 150368326731SBarry Smith if (flg) { 1504a0324ebeSBarry Smith int level=3; 1505fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level)); 150668326731SBarry Smith } 15070298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr); 1508fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its)); 15090298fd71SBarry 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); 1510fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax)); 15110298fd71SBarry 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); 1512fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax)); 15139e5bc791SBarry Smith 15140298fd71SBarry Smith ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr); 1515fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels)); 15163b46a515SGlenn Hammond 15170298fd71SBarry Smith ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr); 1518fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol)); 15190298fd71SBarry 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); 1520fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type)); 15210298fd71SBarry Smith ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr); 1522fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type)); 1523ebc551c0SBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 1524ebc551c0SBarry Smith PetscFunctionReturn(0); 1525ebc551c0SBarry Smith } 1526ebc551c0SBarry Smith 1527f91d8e95SBarry Smith #undef __FUNCT__ 1528f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG" 1529f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y) 1530f91d8e95SBarry Smith { 1531f91d8e95SBarry Smith PetscErrorCode ierr; 1532f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG*) pc->data; 1533f91d8e95SBarry Smith PetscScalar *xx,*yy; 15344ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 153568326731SBarry Smith Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 1536f91d8e95SBarry Smith 1537f91d8e95SBarry Smith PetscFunctionBegin; 1538dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1539aa219208SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1540f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 1541f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 1542f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 1543f91d8e95SBarry Smith 1544f91d8e95SBarry Smith /* copy x values over to hypre */ 1545fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0)); 1546f91d8e95SBarry Smith ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 15478b1f7689SBarry Smith PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,xx)); 1548f91d8e95SBarry Smith ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 1549fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb)); 1550fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx)); 1551f91d8e95SBarry Smith 1552f91d8e95SBarry Smith /* copy solution values back to PETSc */ 1553f91d8e95SBarry Smith ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 15548b1f7689SBarry Smith PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy)); 1555f91d8e95SBarry Smith ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1556f91d8e95SBarry Smith PetscFunctionReturn(0); 1557f91d8e95SBarry Smith } 1558f91d8e95SBarry Smith 15599e5bc791SBarry Smith #undef __FUNCT__ 15609e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG" 1561ace3abfcSBarry 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) 15629e5bc791SBarry Smith { 15639e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG*)pc->data; 15649e5bc791SBarry Smith PetscErrorCode ierr; 15654ddd07fcSJed Brown PetscInt oits; 15669e5bc791SBarry Smith 15679e5bc791SBarry Smith PetscFunctionBegin; 1568dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1569fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its)); 1570fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol)); 15719e5bc791SBarry Smith 15729e5bc791SBarry Smith ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr); 15738b1f7689SBarry Smith PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits)); 15749e5bc791SBarry Smith *outits = oits; 15759e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 15769e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1577fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol)); 1578fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its)); 15799e5bc791SBarry Smith PetscFunctionReturn(0); 15809e5bc791SBarry Smith } 15819e5bc791SBarry Smith 15829e5bc791SBarry Smith 15833a32d3dbSGlenn Hammond #undef __FUNCT__ 15843a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG" 15853a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc) 15863a32d3dbSGlenn Hammond { 15873a32d3dbSGlenn Hammond PetscErrorCode ierr; 15883a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG*) pc->data; 15893a32d3dbSGlenn Hammond Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data); 1590ace3abfcSBarry Smith PetscBool flg; 15913a32d3dbSGlenn Hammond 15923a32d3dbSGlenn Hammond PetscFunctionBegin; 1593251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr); 1594ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner"); 15953a32d3dbSGlenn Hammond 15963a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 15972fa5cd67SKarl Rupp if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver)); 1598fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver)); 1599fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx)); 1600fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver)); 16013a32d3dbSGlenn Hammond PetscFunctionReturn(0); 16023a32d3dbSGlenn Hammond } 16033a32d3dbSGlenn Hammond 1604ebc551c0SBarry Smith 1605ebc551c0SBarry Smith /*MC 1606ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 1607ebc551c0SBarry Smith 1608ebc551c0SBarry Smith Level: advanced 1609ebc551c0SBarry Smith 16109e5bc791SBarry Smith Options Database: 16119e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner 16129e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid 16139e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid 16149e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG 16159e5bc791SBarry 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 16169e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 1617f91d8e95SBarry Smith 16189e5bc791SBarry Smith Notes: This is for CELL-centered descretizations 16199e5bc791SBarry Smith 16208e395302SJed Brown This must be used with the MATHYPRESTRUCT matrix type. 1621aa219208SBarry Smith This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA. 16229e5bc791SBarry Smith 16239e5bc791SBarry Smith .seealso: PCMG, MATHYPRESTRUCT 1624ebc551c0SBarry Smith M*/ 1625ebc551c0SBarry Smith 1626ebc551c0SBarry Smith #undef __FUNCT__ 1627ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG" 16288cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 1629ebc551c0SBarry Smith { 1630ebc551c0SBarry Smith PetscErrorCode ierr; 1631ebc551c0SBarry Smith PC_PFMG *ex; 1632ebc551c0SBarry Smith 1633ebc551c0SBarry Smith PetscFunctionBegin; 1634b00a9115SJed Brown ierr = PetscNew(&ex);CHKERRQ(ierr); \ 163568326731SBarry Smith pc->data = ex; 1636ebc551c0SBarry Smith 16379e5bc791SBarry Smith ex->its = 1; 16389e5bc791SBarry Smith ex->tol = 1.e-8; 16399e5bc791SBarry Smith ex->relax_type = 1; 16409e5bc791SBarry Smith ex->rap_type = 0; 16419e5bc791SBarry Smith ex->num_pre_relax = 1; 16429e5bc791SBarry Smith ex->num_post_relax = 1; 16433b46a515SGlenn Hammond ex->max_levels = 0; 16449e5bc791SBarry Smith 1645ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 1646ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 1647ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 1648f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 16499e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 165068326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 16512fa5cd67SKarl Rupp 1652ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr); 1653fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver)); 1654ebc551c0SBarry Smith PetscFunctionReturn(0); 1655ebc551c0SBarry Smith } 1656d851a50bSGlenn Hammond 1657325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/ 1658325fc9f4SBarry Smith 1659d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 1660d851a50bSGlenn Hammond typedef struct { 1661d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 1662d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 1663d851a50bSGlenn Hammond 1664d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 16654ddd07fcSJed Brown PetscInt its; 1666d851a50bSGlenn Hammond double tol; 16674ddd07fcSJed Brown PetscInt relax_type; 16684ddd07fcSJed Brown PetscInt num_pre_relax,num_post_relax; 1669d851a50bSGlenn Hammond } PC_SysPFMG; 1670d851a50bSGlenn Hammond 1671d851a50bSGlenn Hammond #undef __FUNCT__ 1672d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG" 1673d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc) 1674d851a50bSGlenn Hammond { 1675d851a50bSGlenn Hammond PetscErrorCode ierr; 1676d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1677d851a50bSGlenn Hammond 1678d851a50bSGlenn Hammond PetscFunctionBegin; 16792fa5cd67SKarl Rupp if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver)); 1680d851a50bSGlenn Hammond ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr); 1681c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 1682d851a50bSGlenn Hammond PetscFunctionReturn(0); 1683d851a50bSGlenn Hammond } 1684d851a50bSGlenn Hammond 1685d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"}; 1686d851a50bSGlenn Hammond 1687d851a50bSGlenn Hammond #undef __FUNCT__ 1688d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG" 1689d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer) 1690d851a50bSGlenn Hammond { 1691d851a50bSGlenn Hammond PetscErrorCode ierr; 1692ace3abfcSBarry Smith PetscBool iascii; 1693d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1694d851a50bSGlenn Hammond 1695d851a50bSGlenn Hammond PetscFunctionBegin; 1696251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1697d851a50bSGlenn Hammond if (iascii) { 1698d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr); 1699d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr); 1700d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr); 1701d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr); 1702d851a50bSGlenn Hammond ierr = PetscViewerASCIIPrintf(viewer," HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr); 1703d851a50bSGlenn Hammond } 1704d851a50bSGlenn Hammond PetscFunctionReturn(0); 1705d851a50bSGlenn Hammond } 1706d851a50bSGlenn Hammond 1707d851a50bSGlenn Hammond 1708d851a50bSGlenn Hammond #undef __FUNCT__ 1709d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG" 17108c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc) 1711d851a50bSGlenn Hammond { 1712d851a50bSGlenn Hammond PetscErrorCode ierr; 1713d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1714ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1715d851a50bSGlenn Hammond 1716d851a50bSGlenn Hammond PetscFunctionBegin; 1717e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr); 17180298fd71SBarry Smith ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr); 1719d851a50bSGlenn Hammond if (flg) { 1720d851a50bSGlenn Hammond int level=3; 1721fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level)); 1722d851a50bSGlenn Hammond } 17230298fd71SBarry Smith ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr); 1724fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its)); 17250298fd71SBarry 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); 1726fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax)); 17270298fd71SBarry 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); 1728fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax)); 1729d851a50bSGlenn Hammond 17300298fd71SBarry Smith ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr); 1731fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol)); 17320298fd71SBarry 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); 1733fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type)); 1734d851a50bSGlenn Hammond ierr = PetscOptionsTail();CHKERRQ(ierr); 1735d851a50bSGlenn Hammond PetscFunctionReturn(0); 1736d851a50bSGlenn Hammond } 1737d851a50bSGlenn Hammond 1738d851a50bSGlenn Hammond #undef __FUNCT__ 1739d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG" 1740d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y) 1741d851a50bSGlenn Hammond { 1742d851a50bSGlenn Hammond PetscErrorCode ierr; 1743d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1744d851a50bSGlenn Hammond PetscScalar *xx,*yy; 17454ddd07fcSJed Brown PetscInt ilower[3],iupper[3]; 1746d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 17474ddd07fcSJed Brown PetscInt ordering= mx->dofs_order; 17484ddd07fcSJed Brown PetscInt nvars = mx->nvars; 17494ddd07fcSJed Brown PetscInt part = 0; 17504ddd07fcSJed Brown PetscInt size; 17514ddd07fcSJed Brown PetscInt i; 1752d851a50bSGlenn Hammond 1753d851a50bSGlenn Hammond PetscFunctionBegin; 1754dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1755aa219208SBarry Smith ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr); 1756d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 1757d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 1758d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 1759d851a50bSGlenn Hammond 1760d851a50bSGlenn Hammond size = 1; 17612fa5cd67SKarl Rupp for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1); 17622fa5cd67SKarl Rupp 1763d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 1764d851a50bSGlenn Hammond if (ordering) { 1765fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0)); 1766d851a50bSGlenn Hammond ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 17678b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,xx+(size*i))); 1768d851a50bSGlenn Hammond ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 1769fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b)); 1770fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x)); 1771fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1772d851a50bSGlenn Hammond 1773d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 1774d851a50bSGlenn Hammond ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 17758b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i))); 1776d851a50bSGlenn Hammond ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1777a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 1778d851a50bSGlenn Hammond PetscScalar *z; 17794ddd07fcSJed Brown PetscInt j, k; 1780d851a50bSGlenn Hammond 1781785e854fSJed Brown ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr); 1782fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0)); 1783d851a50bSGlenn Hammond ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 1784d851a50bSGlenn Hammond 1785d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 1786d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 1787d851a50bSGlenn Hammond k= i*nvars; 17882fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j]; 1789d851a50bSGlenn Hammond } 17908b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i))); 1791d851a50bSGlenn Hammond ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 1792fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b)); 1793fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1794d851a50bSGlenn Hammond 1795d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 1796d851a50bSGlenn Hammond ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 17978b1f7689SBarry Smith for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i))); 1798d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 1799d851a50bSGlenn Hammond for (i= 0; i< size; i++) { 1800d851a50bSGlenn Hammond k= i*nvars; 18012fa5cd67SKarl Rupp for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i]; 1802d851a50bSGlenn Hammond } 1803d851a50bSGlenn Hammond ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 1804d851a50bSGlenn Hammond ierr = PetscFree(z);CHKERRQ(ierr); 1805d851a50bSGlenn Hammond } 1806d851a50bSGlenn Hammond PetscFunctionReturn(0); 1807d851a50bSGlenn Hammond } 1808d851a50bSGlenn Hammond 1809d851a50bSGlenn Hammond #undef __FUNCT__ 1810d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG" 1811ace3abfcSBarry 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) 1812d851a50bSGlenn Hammond { 1813d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG*)pc->data; 1814d851a50bSGlenn Hammond PetscErrorCode ierr; 18154ddd07fcSJed Brown PetscInt oits; 1816d851a50bSGlenn Hammond 1817d851a50bSGlenn Hammond PetscFunctionBegin; 1818dff31646SBarry Smith ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr); 1819fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its)); 1820fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol)); 1821d851a50bSGlenn Hammond ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr); 18228b1f7689SBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits)); 1823d851a50bSGlenn Hammond *outits = oits; 1824d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 1825d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 1826fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol)); 1827fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its)); 1828d851a50bSGlenn Hammond PetscFunctionReturn(0); 1829d851a50bSGlenn Hammond } 1830d851a50bSGlenn Hammond 1831d851a50bSGlenn Hammond 1832d851a50bSGlenn Hammond #undef __FUNCT__ 1833d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG" 1834d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc) 1835d851a50bSGlenn Hammond { 1836d851a50bSGlenn Hammond PetscErrorCode ierr; 1837d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG*) pc->data; 1838d851a50bSGlenn Hammond Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data); 1839ace3abfcSBarry Smith PetscBool flg; 1840d851a50bSGlenn Hammond 1841d851a50bSGlenn Hammond PetscFunctionBegin; 1842251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr); 1843ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner"); 1844d851a50bSGlenn Hammond 1845d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 18462fa5cd67SKarl Rupp if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver)); 1847fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver)); 1848fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver)); 1849fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x)); 1850d851a50bSGlenn Hammond PetscFunctionReturn(0); 1851d851a50bSGlenn Hammond } 1852d851a50bSGlenn Hammond 1853d851a50bSGlenn Hammond 1854d851a50bSGlenn Hammond /*MC 1855d851a50bSGlenn Hammond PCSysPFMG - the hypre SysPFMG multigrid solver 1856d851a50bSGlenn Hammond 1857d851a50bSGlenn Hammond Level: advanced 1858d851a50bSGlenn Hammond 1859d851a50bSGlenn Hammond Options Database: 1860d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner 1861d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid 1862d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid 1863d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG 1864d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel 1865d851a50bSGlenn Hammond 1866d851a50bSGlenn Hammond Notes: This is for CELL-centered descretizations 1867d851a50bSGlenn Hammond 1868f6680f47SSatish Balay This must be used with the MATHYPRESSTRUCT matrix type. 1869aa219208SBarry Smith This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA. 1870d851a50bSGlenn Hammond Also, only cell-centered variables. 1871d851a50bSGlenn Hammond 1872d851a50bSGlenn Hammond .seealso: PCMG, MATHYPRESSTRUCT 1873d851a50bSGlenn Hammond M*/ 1874d851a50bSGlenn Hammond 1875d851a50bSGlenn Hammond #undef __FUNCT__ 1876d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG" 18778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 1878d851a50bSGlenn Hammond { 1879d851a50bSGlenn Hammond PetscErrorCode ierr; 1880d851a50bSGlenn Hammond PC_SysPFMG *ex; 1881d851a50bSGlenn Hammond 1882d851a50bSGlenn Hammond PetscFunctionBegin; 1883b00a9115SJed Brown ierr = PetscNew(&ex);CHKERRQ(ierr); \ 1884d851a50bSGlenn Hammond pc->data = ex; 1885d851a50bSGlenn Hammond 1886d851a50bSGlenn Hammond ex->its = 1; 1887d851a50bSGlenn Hammond ex->tol = 1.e-8; 1888d851a50bSGlenn Hammond ex->relax_type = 1; 1889d851a50bSGlenn Hammond ex->num_pre_relax = 1; 1890d851a50bSGlenn Hammond ex->num_post_relax = 1; 1891d851a50bSGlenn Hammond 1892d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 1893d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 1894d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 1895d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 1896d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 1897d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 18982fa5cd67SKarl Rupp 1899ce94432eSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr); 1900fd3f9acdSBarry Smith PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver)); 1901d851a50bSGlenn Hammond PetscFunctionReturn(0); 1902d851a50bSGlenn Hammond } 1903