1dba47a55SKris Buschelman #define PETSCKSP_DLL 2dba47a55SKris Buschelman 34b9ad928SBarry Smith /* 44b9ad928SBarry Smith Defines the multigrid preconditioner interface. 54b9ad928SBarry Smith */ 64b9ad928SBarry Smith #include "src/ksp/pc/impls/mg/mgimpl.h" /*I "petscmg.h" I*/ 74b9ad928SBarry Smith 84b9ad928SBarry Smith 94b9ad928SBarry Smith #undef __FUNCT__ 109dcbbd2bSBarry Smith #define __FUNCT__ "PCMGMCycle_Private" 111e2582c4SBarry Smith PetscErrorCode PCMGMCycle_Private(PC pc,PC_MG **mglevels,PetscTruth *converged) 124b9ad928SBarry Smith { 139dcbbd2bSBarry Smith PC_MG *mg = *mglevels,*mgc; 146849ba73SBarry Smith PetscErrorCode ierr; 150d353602SBarry Smith PetscInt cycles = (PetscInt) mg->cycles; 164b9ad928SBarry Smith 174b9ad928SBarry Smith PetscFunctionBegin; 184b9ad928SBarry Smith if (converged) *converged = PETSC_FALSE; 194b9ad928SBarry Smith 2032cf1786SBarry Smith if (mg->eventsmoothsolve) {ierr = PetscLogEventBegin(mg->eventsmoothsolve,0,0,0,0);CHKERRQ(ierr);} 210d353602SBarry Smith ierr = KSPSolve(mg->smoothd,mg->b,mg->x);CHKERRQ(ierr); /* pre-smooth */ 2232cf1786SBarry Smith if (mg->eventsmoothsolve) {ierr = PetscLogEventEnd(mg->eventsmoothsolve,0,0,0,0);CHKERRQ(ierr);} 234b9ad928SBarry Smith if (mg->level) { /* not the coarsest grid */ 2432cf1786SBarry Smith if (mg->eventresidual) {ierr = PetscLogEventBegin(mg->eventresidual,0,0,0,0);CHKERRQ(ierr);} 254b9ad928SBarry Smith ierr = (*mg->residual)(mg->A,mg->b,mg->x,mg->r);CHKERRQ(ierr); 2632cf1786SBarry Smith if (mg->eventresidual) {ierr = PetscLogEventEnd(mg->eventresidual,0,0,0,0);CHKERRQ(ierr);} 274b9ad928SBarry Smith 284b9ad928SBarry Smith /* if on finest level and have convergence criteria set */ 294b9ad928SBarry Smith if (mg->level == mg->levels-1 && mg->ttol) { 304b9ad928SBarry Smith PetscReal rnorm; 314b9ad928SBarry Smith ierr = VecNorm(mg->r,NORM_2,&rnorm);CHKERRQ(ierr); 324b9ad928SBarry Smith if (rnorm <= mg->ttol) { 334b9ad928SBarry Smith *converged = PETSC_TRUE; 3470441072SBarry Smith if (rnorm < mg->abstol) { 351e2582c4SBarry Smith ierr = PetscInfo2(pc,"Linear solver has converged. Residual norm %G is less than absolute tolerance %G\n",rnorm,mg->abstol);CHKERRQ(ierr); 364b9ad928SBarry Smith } else { 371e2582c4SBarry Smith ierr = PetscInfo2(pc,"Linear solver has converged. Residual norm %G is less than relative tolerance times initial residual norm %G\n",rnorm,mg->ttol);CHKERRQ(ierr); 384b9ad928SBarry Smith } 394b9ad928SBarry Smith PetscFunctionReturn(0); 404b9ad928SBarry Smith } 414b9ad928SBarry Smith } 424b9ad928SBarry Smith 434b9ad928SBarry Smith mgc = *(mglevels - 1); 4432cf1786SBarry Smith if (mg->eventinterprestrict) {ierr = PetscLogEventBegin(mg->eventinterprestrict,0,0,0,0);CHKERRQ(ierr);} 454b9ad928SBarry Smith ierr = MatRestrict(mg->restrct,mg->r,mgc->b);CHKERRQ(ierr); 4632cf1786SBarry Smith if (mg->eventinterprestrict) {ierr = PetscLogEventEnd(mg->eventinterprestrict,0,0,0,0);CHKERRQ(ierr);} 47efb30889SBarry Smith ierr = VecSet(mgc->x,0.0);CHKERRQ(ierr); 484b9ad928SBarry Smith while (cycles--) { 491e2582c4SBarry Smith ierr = PCMGMCycle_Private(pc,mglevels-1,converged);CHKERRQ(ierr); 504b9ad928SBarry Smith } 5132cf1786SBarry Smith if (mg->eventinterprestrict) {ierr = PetscLogEventBegin(mg->eventinterprestrict,0,0,0,0);CHKERRQ(ierr);} 524b9ad928SBarry Smith ierr = MatInterpolateAdd(mg->interpolate,mgc->x,mg->x,mg->x);CHKERRQ(ierr); 5332cf1786SBarry Smith if (mg->eventinterprestrict) {ierr = PetscLogEventEnd(mg->eventinterprestrict,0,0,0,0);CHKERRQ(ierr);} 5432cf1786SBarry Smith if (mg->eventsmoothsolve) {ierr = PetscLogEventBegin(mg->eventsmoothsolve,0,0,0,0);CHKERRQ(ierr);} 550d353602SBarry Smith ierr = KSPSolve(mg->smoothu,mg->b,mg->x);CHKERRQ(ierr); /* post smooth */ 5632cf1786SBarry Smith if (mg->eventsmoothsolve) {ierr = PetscLogEventEnd(mg->eventsmoothsolve,0,0,0,0);CHKERRQ(ierr);} 574b9ad928SBarry Smith } 584b9ad928SBarry Smith PetscFunctionReturn(0); 594b9ad928SBarry Smith } 604b9ad928SBarry Smith 614b9ad928SBarry Smith /* 629dcbbd2bSBarry Smith PCMGCreate_Private - Creates a PC_MG structure for use with the 634b9ad928SBarry Smith multigrid code. Level 0 is the coarsest. (But the 644b9ad928SBarry Smith finest level is stored first in the array). 654b9ad928SBarry Smith 664b9ad928SBarry Smith */ 674b9ad928SBarry Smith #undef __FUNCT__ 689dcbbd2bSBarry Smith #define __FUNCT__ "PCMGCreate_Private" 699dcbbd2bSBarry Smith static PetscErrorCode PCMGCreate_Private(MPI_Comm comm,PetscInt levels,PC pc,MPI_Comm *comms,PC_MG ***result) 704b9ad928SBarry Smith { 719dcbbd2bSBarry Smith PC_MG **mg; 726849ba73SBarry Smith PetscErrorCode ierr; 7379416396SBarry Smith PetscInt i; 7479416396SBarry Smith PetscMPIInt size; 75f69a0ea3SMatthew Knepley const char *prefix; 764b9ad928SBarry Smith PC ipc; 774b9ad928SBarry Smith 784b9ad928SBarry Smith PetscFunctionBegin; 799dcbbd2bSBarry Smith ierr = PetscMalloc(levels*sizeof(PC_MG*),&mg);CHKERRQ(ierr); 8038f2d2fdSLisandro Dalcin ierr = PetscLogObjectMemory(pc,levels*(sizeof(PC_MG*)));CHKERRQ(ierr); 814b9ad928SBarry Smith 824b9ad928SBarry Smith ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 834b9ad928SBarry Smith 844b9ad928SBarry Smith for (i=0; i<levels; i++) { 8538f2d2fdSLisandro Dalcin ierr = PetscNewLog(pc,PC_MG,&mg[i]);CHKERRQ(ierr); 864b9ad928SBarry Smith mg[i]->level = i; 874b9ad928SBarry Smith mg[i]->levels = levels; 880d353602SBarry Smith mg[i]->cycles = PC_MG_CYCLE_V; 89c2be2410SBarry Smith mg[i]->galerkin = PETSC_FALSE; 90c2be2410SBarry Smith mg[i]->galerkinused = PETSC_FALSE; 9179416396SBarry Smith mg[i]->default_smoothu = 1; 9279416396SBarry Smith mg[i]->default_smoothd = 1; 934b9ad928SBarry Smith 944b9ad928SBarry Smith if (comms) comm = comms[i]; 954b9ad928SBarry Smith ierr = KSPCreate(comm,&mg[i]->smoothd);CHKERRQ(ierr); 9679416396SBarry Smith ierr = KSPSetTolerances(mg[i]->smoothd,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT, mg[i]->default_smoothd);CHKERRQ(ierr); 974b9ad928SBarry Smith ierr = KSPSetOptionsPrefix(mg[i]->smoothd,prefix);CHKERRQ(ierr); 984b9ad928SBarry Smith 994b9ad928SBarry Smith /* do special stuff for coarse grid */ 1004b9ad928SBarry Smith if (!i && levels > 1) { 1014b9ad928SBarry Smith ierr = KSPAppendOptionsPrefix(mg[0]->smoothd,"mg_coarse_");CHKERRQ(ierr); 1024b9ad928SBarry Smith 1034b9ad928SBarry Smith /* coarse solve is (redundant) LU by default */ 1044b9ad928SBarry Smith ierr = KSPSetType(mg[0]->smoothd,KSPPREONLY);CHKERRQ(ierr); 1054b9ad928SBarry Smith ierr = KSPGetPC(mg[0]->smoothd,&ipc);CHKERRQ(ierr); 1064b9ad928SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1074b9ad928SBarry Smith if (size > 1) { 1084b9ad928SBarry Smith ierr = PCSetType(ipc,PCREDUNDANT);CHKERRQ(ierr); 1090d7810c8SBarry Smith } else { 1104b9ad928SBarry Smith ierr = PCSetType(ipc,PCLU);CHKERRQ(ierr); 1110d7810c8SBarry Smith } 1124b9ad928SBarry Smith 1134b9ad928SBarry Smith } else { 1142e70eadcSBarry Smith char tprefix[128]; 11513f74950SBarry Smith sprintf(tprefix,"mg_levels_%d_",(int)i); 1162e70eadcSBarry Smith ierr = KSPAppendOptionsPrefix(mg[i]->smoothd,tprefix);CHKERRQ(ierr); 1174b9ad928SBarry Smith } 11852e6d16bSBarry Smith ierr = PetscLogObjectParent(pc,mg[i]->smoothd);CHKERRQ(ierr); 1194b9ad928SBarry Smith mg[i]->smoothu = mg[i]->smoothd; 1204b9ad928SBarry Smith mg[i]->rtol = 0.0; 12170441072SBarry Smith mg[i]->abstol = 0.0; 1224b9ad928SBarry Smith mg[i]->dtol = 0.0; 1234b9ad928SBarry Smith mg[i]->ttol = 0.0; 12432cf1786SBarry Smith mg[i]->eventsmoothsetup = 0; 12532cf1786SBarry Smith mg[i]->eventsmoothsolve = 0; 12632cf1786SBarry Smith mg[i]->eventresidual = 0; 12732cf1786SBarry Smith mg[i]->eventinterprestrict = 0; 1288cc2d5dfSBarry Smith mg[i]->cyclesperpcapply = 1; 1294b9ad928SBarry Smith } 1304b9ad928SBarry Smith *result = mg; 1314b9ad928SBarry Smith PetscFunctionReturn(0); 1324b9ad928SBarry Smith } 1334b9ad928SBarry Smith 1344b9ad928SBarry Smith #undef __FUNCT__ 1354b9ad928SBarry Smith #define __FUNCT__ "PCDestroy_MG" 1366849ba73SBarry Smith static PetscErrorCode PCDestroy_MG(PC pc) 1374b9ad928SBarry Smith { 1389dcbbd2bSBarry Smith PC_MG **mg = (PC_MG**)pc->data; 1396849ba73SBarry Smith PetscErrorCode ierr; 14038f2d2fdSLisandro Dalcin PetscInt i,n; 1414b9ad928SBarry Smith 1424b9ad928SBarry Smith PetscFunctionBegin; 14338f2d2fdSLisandro Dalcin if (!mg) PetscFunctionReturn(0); 14438f2d2fdSLisandro Dalcin n = mg[0]->levels; 145fccaa45eSBarry Smith for (i=0; i<n-1; i++) { 146630ba2eeSBarry Smith if (mg[i+1]->r) {ierr = VecDestroy(mg[i+1]->r);CHKERRQ(ierr);} 147fccaa45eSBarry Smith if (mg[i]->b) {ierr = VecDestroy(mg[i]->b);CHKERRQ(ierr);} 148fccaa45eSBarry Smith if (mg[i]->x) {ierr = VecDestroy(mg[i]->x);CHKERRQ(ierr);} 149fccaa45eSBarry Smith if (mg[i+1]->restrct) {ierr = MatDestroy(mg[i+1]->restrct);CHKERRQ(ierr);} 150fccaa45eSBarry Smith if (mg[i+1]->interpolate) {ierr = MatDestroy(mg[i+1]->interpolate);CHKERRQ(ierr);} 151fccaa45eSBarry Smith } 152fccaa45eSBarry Smith 1534b9ad928SBarry Smith for (i=0; i<n; i++) { 1544b9ad928SBarry Smith if (mg[i]->smoothd != mg[i]->smoothu) { 1554b9ad928SBarry Smith ierr = KSPDestroy(mg[i]->smoothd);CHKERRQ(ierr); 1564b9ad928SBarry Smith } 1574b9ad928SBarry Smith ierr = KSPDestroy(mg[i]->smoothu);CHKERRQ(ierr); 1584b9ad928SBarry Smith ierr = PetscFree(mg[i]);CHKERRQ(ierr); 1594b9ad928SBarry Smith } 1604b9ad928SBarry Smith ierr = PetscFree(mg);CHKERRQ(ierr); 1614b9ad928SBarry Smith PetscFunctionReturn(0); 1624b9ad928SBarry Smith } 1634b9ad928SBarry Smith 1644b9ad928SBarry Smith 1654b9ad928SBarry Smith 1669dcbbd2bSBarry Smith EXTERN PetscErrorCode PCMGACycle_Private(PC_MG**); 1671e2582c4SBarry Smith EXTERN PetscErrorCode PCMGFCycle_Private(PC,PC_MG**); 1689dcbbd2bSBarry Smith EXTERN PetscErrorCode PCMGKCycle_Private(PC_MG**); 1694b9ad928SBarry Smith 1704b9ad928SBarry Smith /* 1714b9ad928SBarry Smith PCApply_MG - Runs either an additive, multiplicative, Kaskadic 1724b9ad928SBarry Smith or full cycle of multigrid. 1734b9ad928SBarry Smith 1744b9ad928SBarry Smith Note: 1759dcbbd2bSBarry Smith A simple wrapper which calls PCMGMCycle(),PCMGACycle(), or PCMGFCycle(). 1764b9ad928SBarry Smith */ 1774b9ad928SBarry Smith #undef __FUNCT__ 1784b9ad928SBarry Smith #define __FUNCT__ "PCApply_MG" 1796849ba73SBarry Smith static PetscErrorCode PCApply_MG(PC pc,Vec b,Vec x) 1804b9ad928SBarry Smith { 1819dcbbd2bSBarry Smith PC_MG **mg = (PC_MG**)pc->data; 1826849ba73SBarry Smith PetscErrorCode ierr; 1838cc2d5dfSBarry Smith PetscInt levels = mg[0]->levels,i; 1844b9ad928SBarry Smith 1854b9ad928SBarry Smith PetscFunctionBegin; 1864b9ad928SBarry Smith mg[levels-1]->b = b; 1874b9ad928SBarry Smith mg[levels-1]->x = x; 188ef70c39aSMatthew Knepley if (!mg[levels-1]->r && mg[0]->am != PC_MG_ADDITIVE && levels > 1) { 1890a6bb862SBarry Smith Vec tvec; 1900a6bb862SBarry Smith ierr = VecDuplicate(mg[levels-1]->b,&tvec);CHKERRQ(ierr); 19197177400SBarry Smith ierr = PCMGSetR(pc,levels-1,tvec);CHKERRQ(ierr); 1920a6bb862SBarry Smith ierr = VecDestroy(tvec);CHKERRQ(ierr); 1930a6bb862SBarry Smith } 1949dcbbd2bSBarry Smith if (mg[0]->am == PC_MG_MULTIPLICATIVE) { 195efb30889SBarry Smith ierr = VecSet(x,0.0);CHKERRQ(ierr); 1968cc2d5dfSBarry Smith for (i=0; i<mg[0]->cyclesperpcapply; i++) { 1971e2582c4SBarry Smith ierr = PCMGMCycle_Private(pc,mg+levels-1,PETSC_NULL);CHKERRQ(ierr); 1984b9ad928SBarry Smith } 1998cc2d5dfSBarry Smith } 2009dcbbd2bSBarry Smith else if (mg[0]->am == PC_MG_ADDITIVE) { 2019dcbbd2bSBarry Smith ierr = PCMGACycle_Private(mg);CHKERRQ(ierr); 2024b9ad928SBarry Smith } 2039dcbbd2bSBarry Smith else if (mg[0]->am == PC_MG_KASKADE) { 2049dcbbd2bSBarry Smith ierr = PCMGKCycle_Private(mg);CHKERRQ(ierr); 2054b9ad928SBarry Smith } 2064b9ad928SBarry Smith else { 2071e2582c4SBarry Smith ierr = PCMGFCycle_Private(pc,mg);CHKERRQ(ierr); 2084b9ad928SBarry Smith } 2094b9ad928SBarry Smith PetscFunctionReturn(0); 2104b9ad928SBarry Smith } 2114b9ad928SBarry Smith 2124b9ad928SBarry Smith #undef __FUNCT__ 2134b9ad928SBarry Smith #define __FUNCT__ "PCApplyRichardson_MG" 21479416396SBarry Smith static PetscErrorCode PCApplyRichardson_MG(PC pc,Vec b,Vec x,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its) 2154b9ad928SBarry Smith { 2169dcbbd2bSBarry Smith PC_MG **mg = (PC_MG**)pc->data; 217dfbe8321SBarry Smith PetscErrorCode ierr; 21879416396SBarry Smith PetscInt levels = mg[0]->levels; 2194b9ad928SBarry Smith PetscTruth converged = PETSC_FALSE; 2204b9ad928SBarry Smith 2214b9ad928SBarry Smith PetscFunctionBegin; 2224b9ad928SBarry Smith mg[levels-1]->b = b; 2234b9ad928SBarry Smith mg[levels-1]->x = x; 2244b9ad928SBarry Smith 2254b9ad928SBarry Smith mg[levels-1]->rtol = rtol; 22670441072SBarry Smith mg[levels-1]->abstol = abstol; 2274b9ad928SBarry Smith mg[levels-1]->dtol = dtol; 2284b9ad928SBarry Smith if (rtol) { 2294b9ad928SBarry Smith /* compute initial residual norm for relative convergence test */ 2304b9ad928SBarry Smith PetscReal rnorm; 2314b9ad928SBarry Smith ierr = (*mg[levels-1]->residual)(mg[levels-1]->A,b,x,w);CHKERRQ(ierr); 2324b9ad928SBarry Smith ierr = VecNorm(w,NORM_2,&rnorm);CHKERRQ(ierr); 23370441072SBarry Smith mg[levels-1]->ttol = PetscMax(rtol*rnorm,abstol); 23470441072SBarry Smith } else if (abstol) { 23570441072SBarry Smith mg[levels-1]->ttol = abstol; 2364b9ad928SBarry Smith } else { 2374b9ad928SBarry Smith mg[levels-1]->ttol = 0.0; 2384b9ad928SBarry Smith } 2394b9ad928SBarry Smith 2404b9ad928SBarry Smith while (its-- && !converged) { 2411e2582c4SBarry Smith ierr = PCMGMCycle_Private(pc,mg+levels-1,&converged);CHKERRQ(ierr); 2424b9ad928SBarry Smith } 2434b9ad928SBarry Smith PetscFunctionReturn(0); 2444b9ad928SBarry Smith } 2454b9ad928SBarry Smith 2464b9ad928SBarry Smith #undef __FUNCT__ 2474b9ad928SBarry Smith #define __FUNCT__ "PCSetFromOptions_MG" 2486ca4d86aSHong Zhang PetscErrorCode PCSetFromOptions_MG(PC pc) 2494b9ad928SBarry Smith { 250dfbe8321SBarry Smith PetscErrorCode ierr; 2518cc2d5dfSBarry Smith PetscInt m,levels = 1,cycles; 2524b9ad928SBarry Smith PetscTruth flg; 2539dcbbd2bSBarry Smith PC_MG **mg = (PC_MG**)pc->data; 25490da95b0SMatthew Knepley PCMGType mgtype = PC_MG_ADDITIVE; 2551aa34eeaSBarry Smith PCMGCycleType mgctype; 2564b9ad928SBarry Smith 2574b9ad928SBarry Smith PetscFunctionBegin; 2584b9ad928SBarry Smith ierr = PetscOptionsHead("Multigrid options");CHKERRQ(ierr); 2594b9ad928SBarry Smith if (!pc->data) { 2609dcbbd2bSBarry Smith ierr = PetscOptionsInt("-pc_mg_levels","Number of Levels","PCMGSetLevels",levels,&levels,&flg);CHKERRQ(ierr); 26197177400SBarry Smith ierr = PCMGSetLevels(pc,levels,PETSC_NULL);CHKERRQ(ierr); 262cf502942SBarry Smith mg = (PC_MG**)pc->data; 2634b9ad928SBarry Smith } 264f2070a76SMatthew Knepley mgctype = (PCMGCycleType) mg[0]->cycles; 2650d353602SBarry Smith ierr = PetscOptionsEnum("-pc_mg_cycle_type","V cycle or for W-cycle","PCMGSetCycleType",PCMGCycleTypes,(PetscEnum)mgctype,(PetscEnum*)&mgctype,&flg);CHKERRQ(ierr); 2664b9ad928SBarry Smith if (flg) { 2670d353602SBarry Smith ierr = PCMGSetCycleType(pc,mgctype);CHKERRQ(ierr); 2680d353602SBarry Smith }; 2699dcbbd2bSBarry Smith ierr = PetscOptionsName("-pc_mg_galerkin","Use Galerkin process to compute coarser operators","PCMGSetGalerkin",&flg);CHKERRQ(ierr); 270c2be2410SBarry Smith if (flg) { 27197177400SBarry Smith ierr = PCMGSetGalerkin(pc);CHKERRQ(ierr); 272c2be2410SBarry Smith } 2739dcbbd2bSBarry Smith ierr = PetscOptionsInt("-pc_mg_smoothup","Number of post-smoothing steps","PCMGSetNumberSmoothUp",1,&m,&flg);CHKERRQ(ierr); 2744b9ad928SBarry Smith if (flg) { 27597177400SBarry Smith ierr = PCMGSetNumberSmoothUp(pc,m);CHKERRQ(ierr); 2764b9ad928SBarry Smith } 2779dcbbd2bSBarry Smith ierr = PetscOptionsInt("-pc_mg_smoothdown","Number of pre-smoothing steps","PCMGSetNumberSmoothDown",1,&m,&flg);CHKERRQ(ierr); 2784b9ad928SBarry Smith if (flg) { 27997177400SBarry Smith ierr = PCMGSetNumberSmoothDown(pc,m);CHKERRQ(ierr); 2804b9ad928SBarry Smith } 2819dcbbd2bSBarry Smith ierr = PetscOptionsEnum("-pc_mg_type","Multigrid type","PCMGSetType",PCMGTypes,(PetscEnum)mgtype,(PetscEnum*)&mgtype,&flg);CHKERRQ(ierr); 2828cc2d5dfSBarry Smith if (flg) { 2838cc2d5dfSBarry Smith ierr = PCMGSetType(pc,mgtype);CHKERRQ(ierr); 2848cc2d5dfSBarry Smith } 2858cc2d5dfSBarry Smith if (mg[0]->am == PC_MG_MULTIPLICATIVE) { 2868cc2d5dfSBarry Smith ierr = PetscOptionsInt("-pc_mg_multiplicative_cycles","Number of cycles for each preconditioner step","PCMGSetLevels",mg[0]->cyclesperpcapply,&cycles,&flg);CHKERRQ(ierr); 2878cc2d5dfSBarry Smith if (flg) { 2888cc2d5dfSBarry Smith ierr = PCMGMultiplicativeSetCycles(pc,cycles);CHKERRQ(ierr); 2898cc2d5dfSBarry Smith } 2908cc2d5dfSBarry Smith } 2914b9ad928SBarry Smith ierr = PetscOptionsName("-pc_mg_log","Log times for each multigrid level","None",&flg);CHKERRQ(ierr); 2924b9ad928SBarry Smith if (flg) { 2934f5ab15aSBarry Smith PetscInt i; 2944b9ad928SBarry Smith char eventname[128]; 2954b9ad928SBarry Smith if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 2964b9ad928SBarry Smith levels = mg[0]->levels; 2974b9ad928SBarry Smith for (i=0; i<levels; i++) { 29832cf1786SBarry Smith sprintf(eventname,"MGSetup Level %d",(int)i); 2997adad957SLisandro Dalcin ierr = PetscLogEventRegister(&mg[i]->eventsmoothsetup,eventname,((PetscObject)pc)->cookie);CHKERRQ(ierr); 30032cf1786SBarry Smith sprintf(eventname,"MGSmooth Level %d",(int)i); 3017adad957SLisandro Dalcin ierr = PetscLogEventRegister(&mg[i]->eventsmoothsolve,eventname,((PetscObject)pc)->cookie);CHKERRQ(ierr); 30232cf1786SBarry Smith if (i) { 30332cf1786SBarry Smith sprintf(eventname,"MGResid Level %d",(int)i); 3047adad957SLisandro Dalcin ierr = PetscLogEventRegister(&mg[i]->eventresidual,eventname,((PetscObject)pc)->cookie);CHKERRQ(ierr); 30532cf1786SBarry Smith sprintf(eventname,"MGInterp Level %d",(int)i); 3067adad957SLisandro Dalcin ierr = PetscLogEventRegister(&mg[i]->eventinterprestrict,eventname,((PetscObject)pc)->cookie);CHKERRQ(ierr); 30732cf1786SBarry Smith } 3084b9ad928SBarry Smith } 3094b9ad928SBarry Smith } 3104b9ad928SBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 3114b9ad928SBarry Smith PetscFunctionReturn(0); 3124b9ad928SBarry Smith } 3134b9ad928SBarry Smith 3149dcbbd2bSBarry Smith const char *PCMGTypes[] = {"MULTIPLICATIVE","ADDITIVE","FULL","KASKADE","PCMGType","PC_MG",0}; 3150d353602SBarry Smith const char *PCMGCycleTypes[] = {"invalid","v","w","PCMGCycleType","PC_MG_CYCLE",0}; 3169dcbbd2bSBarry Smith 3174b9ad928SBarry Smith #undef __FUNCT__ 3184b9ad928SBarry Smith #define __FUNCT__ "PCView_MG" 3196849ba73SBarry Smith static PetscErrorCode PCView_MG(PC pc,PetscViewer viewer) 3204b9ad928SBarry Smith { 3219dcbbd2bSBarry Smith PC_MG **mg = (PC_MG**)pc->data; 322dfbe8321SBarry Smith PetscErrorCode ierr; 32379416396SBarry Smith PetscInt levels = mg[0]->levels,i; 32432077d6dSBarry Smith PetscTruth iascii; 3254b9ad928SBarry Smith 3264b9ad928SBarry Smith PetscFunctionBegin; 32732077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 32832077d6dSBarry Smith if (iascii) { 3290d353602SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," MG: type is %s, levels=%D cycles=%s, pre-smooths=%D, post-smooths=%D\n", 3300d353602SBarry Smith PCMGTypes[mg[0]->am],levels,(mg[0]->cycles == PC_MG_CYCLE_V) ? "v" : "w", 3310d353602SBarry Smith mg[0]->default_smoothd,mg[0]->default_smoothu);CHKERRQ(ierr); 332c2be2410SBarry Smith if (mg[0]->galerkin) { 333c2be2410SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Using Galerkin computed coarse grid matrices\n");CHKERRQ(ierr); 334c2be2410SBarry Smith } 3354b9ad928SBarry Smith for (i=0; i<levels; i++) { 336b03c7568SBarry Smith if (!i) { 337b03c7568SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Coarse gride solver -- level %D -------------------------------\n",i);CHKERRQ(ierr); 338b03c7568SBarry Smith } else { 33977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Down solver (pre-smoother) on level %D -------------------------------\n",i);CHKERRQ(ierr); 340b03c7568SBarry Smith } 3414b9ad928SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3424b9ad928SBarry Smith ierr = KSPView(mg[i]->smoothd,viewer);CHKERRQ(ierr); 3434b9ad928SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 344b03c7568SBarry Smith if (i && mg[i]->smoothd == mg[i]->smoothu) { 3454b9ad928SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Up solver (post-smoother) same as down solver (pre-smoother)\n");CHKERRQ(ierr); 346b03c7568SBarry Smith } else if (i){ 34777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Up solver (post-smoother) on level %D -------------------------------\n",i);CHKERRQ(ierr); 3484b9ad928SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3494b9ad928SBarry Smith ierr = KSPView(mg[i]->smoothu,viewer);CHKERRQ(ierr); 3504b9ad928SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3514b9ad928SBarry Smith } 3524b9ad928SBarry Smith } 3534b9ad928SBarry Smith } else { 35479a5c55eSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCMG",((PetscObject)viewer)->type_name); 3554b9ad928SBarry Smith } 3564b9ad928SBarry Smith PetscFunctionReturn(0); 3574b9ad928SBarry Smith } 3584b9ad928SBarry Smith 3594b9ad928SBarry Smith /* 3604b9ad928SBarry Smith Calls setup for the KSP on each level 3614b9ad928SBarry Smith */ 3624b9ad928SBarry Smith #undef __FUNCT__ 3634b9ad928SBarry Smith #define __FUNCT__ "PCSetUp_MG" 3646849ba73SBarry Smith static PetscErrorCode PCSetUp_MG(PC pc) 3654b9ad928SBarry Smith { 3669dcbbd2bSBarry Smith PC_MG **mg = (PC_MG**)pc->data; 367dfbe8321SBarry Smith PetscErrorCode ierr; 36879416396SBarry Smith PetscInt i,n = mg[0]->levels; 36977122347SBarry Smith PC cpc,mpc; 370906ed7ccSBarry Smith PetscTruth preonly,lu,redundant,cholesky,monitor = PETSC_FALSE,dump,opsset; 37123d894e5SBarry Smith PetscViewerASCIIMonitor ascii; 37223d894e5SBarry Smith PetscViewer viewer = PETSC_NULL; 3734b9ad928SBarry Smith MPI_Comm comm; 374c2be2410SBarry Smith Mat dA,dB; 375c2be2410SBarry Smith MatStructure uflag; 3760a6bb862SBarry Smith Vec tvec; 3774b9ad928SBarry Smith 3784b9ad928SBarry Smith PetscFunctionBegin; 379852665d3SBarry Smith 38043fb2f97SBarry Smith /* If user did not provide fine grid operators OR operator was not updated since last global KSPSetOperators() */ 38143fb2f97SBarry Smith /* so use those from global PC */ 38243fb2f97SBarry Smith /* Is this what we always want? What if user wants to keep old one? */ 383906ed7ccSBarry Smith ierr = KSPGetOperatorsSet(mg[n-1]->smoothd,PETSC_NULL,&opsset);CHKERRQ(ierr); 38443fb2f97SBarry Smith ierr = KSPGetPC(mg[0]->smoothd,&cpc);CHKERRQ(ierr); 38577122347SBarry Smith ierr = KSPGetPC(mg[n-1]->smoothd,&mpc);CHKERRQ(ierr); 38677122347SBarry Smith if (!opsset || ((cpc->setupcalled == 1) && (mpc->setupcalled == 2))) { 387852665d3SBarry Smith ierr = PetscInfo(pc,"Using outer operators to define finest grid operator \n because PCMGGetSmoother(pc,nlevels-1,&ksp);KSPSetOperators(ksp,...); was not called.\n");CHKERRQ(ierr); 3881cfe3bddSBarry Smith ierr = KSPSetOperators(mg[n-1]->smoothd,pc->mat,pc->pmat,pc->flag);CHKERRQ(ierr); 389852665d3SBarry Smith } 390852665d3SBarry Smith 391852665d3SBarry Smith if (mg[0]->galerkin) { 392852665d3SBarry Smith Mat B; 393852665d3SBarry Smith mg[0]->galerkinused = PETSC_TRUE; 394852665d3SBarry Smith /* currently only handle case where mat and pmat are the same on coarser levels */ 395852665d3SBarry Smith ierr = KSPGetOperators(mg[n-1]->smoothd,&dA,&dB,&uflag);CHKERRQ(ierr); 396852665d3SBarry Smith if (!pc->setupcalled) { 397852665d3SBarry Smith for (i=n-2; i>-1; i--) { 398852665d3SBarry Smith ierr = MatPtAP(dB,mg[i+1]->interpolate,MAT_INITIAL_MATRIX,1.0,&B);CHKERRQ(ierr); 399852665d3SBarry Smith ierr = KSPSetOperators(mg[i]->smoothd,B,B,uflag);CHKERRQ(ierr); 400906ed7ccSBarry Smith if (i != n-2) {ierr = PetscObjectDereference((PetscObject)dB);CHKERRQ(ierr);} 401852665d3SBarry Smith dB = B; 402852665d3SBarry Smith } 403906ed7ccSBarry Smith ierr = PetscObjectDereference((PetscObject)dB);CHKERRQ(ierr); 404852665d3SBarry Smith } else { 405852665d3SBarry Smith for (i=n-2; i>-1; i--) { 406906ed7ccSBarry Smith ierr = KSPGetOperators(mg[i]->smoothd,PETSC_NULL,&B,PETSC_NULL);CHKERRQ(ierr); 407852665d3SBarry Smith ierr = MatPtAP(dB,mg[i+1]->interpolate,MAT_REUSE_MATRIX,1.0,&B);CHKERRQ(ierr); 408852665d3SBarry Smith ierr = KSPSetOperators(mg[i]->smoothd,B,B,uflag);CHKERRQ(ierr); 409852665d3SBarry Smith dB = B; 410852665d3SBarry Smith } 411852665d3SBarry Smith } 412852665d3SBarry Smith } 413852665d3SBarry Smith 414958c9bccSBarry Smith if (!pc->setupcalled) { 4154b9ad928SBarry Smith ierr = PetscOptionsHasName(0,"-pc_mg_monitor",&monitor);CHKERRQ(ierr); 4164b9ad928SBarry Smith 417b03c7568SBarry Smith for (i=0; i<n; i++) { 4184b9ad928SBarry Smith if (monitor) { 4194b9ad928SBarry Smith ierr = PetscObjectGetComm((PetscObject)mg[i]->smoothd,&comm);CHKERRQ(ierr); 42023d894e5SBarry Smith ierr = PetscViewerASCIIMonitorCreate(comm,"stdout",n-i,&ascii);CHKERRQ(ierr); 42123d894e5SBarry Smith ierr = KSPMonitorSet(mg[i]->smoothd,KSPMonitorDefault,ascii,(PetscErrorCode(*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 4224b9ad928SBarry Smith } 4234b9ad928SBarry Smith ierr = KSPSetFromOptions(mg[i]->smoothd);CHKERRQ(ierr); 4244b9ad928SBarry Smith } 425b03c7568SBarry Smith for (i=1; i<n; i++) { 426a98fc643SBarry Smith if (mg[i]->smoothu && (mg[i]->smoothu != mg[i]->smoothd)) { 4274b9ad928SBarry Smith if (monitor) { 4284b9ad928SBarry Smith ierr = PetscObjectGetComm((PetscObject)mg[i]->smoothu,&comm);CHKERRQ(ierr); 42923d894e5SBarry Smith ierr = PetscViewerASCIIMonitorCreate(comm,"stdout",n-i,&ascii);CHKERRQ(ierr); 43023d894e5SBarry Smith ierr = KSPMonitorSet(mg[i]->smoothu,KSPMonitorDefault,ascii,(PetscErrorCode(*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 4314b9ad928SBarry Smith } 4324b9ad928SBarry Smith ierr = KSPSetFromOptions(mg[i]->smoothu);CHKERRQ(ierr); 4334b9ad928SBarry Smith } 4344b9ad928SBarry Smith } 435fccaa45eSBarry Smith for (i=1; i<n; i++) { 4360cace4b0SBarry Smith if (!mg[i]->residual) { 4370cace4b0SBarry Smith Mat mat; 4380cace4b0SBarry Smith ierr = KSPGetOperators(mg[i]->smoothd,PETSC_NULL,&mat,PETSC_NULL);CHKERRQ(ierr); 4390cace4b0SBarry Smith ierr = PCMGSetResidual(pc,i,PCMGDefaultResidual,mat);CHKERRQ(ierr); 4400cace4b0SBarry Smith } 441fccaa45eSBarry Smith if (mg[i]->restrct && !mg[i]->interpolate) { 442aea2a34eSBarry Smith ierr = PCMGSetInterpolation(pc,i,mg[i]->restrct);CHKERRQ(ierr); 443fccaa45eSBarry Smith } 444fccaa45eSBarry Smith if (!mg[i]->restrct && mg[i]->interpolate) { 44597177400SBarry Smith ierr = PCMGSetRestriction(pc,i,mg[i]->interpolate);CHKERRQ(ierr); 446fccaa45eSBarry Smith } 447fccaa45eSBarry Smith #if defined(PETSC_USE_DEBUG) 448fccaa45eSBarry Smith if (!mg[i]->restrct || !mg[i]->interpolate) { 449fccaa45eSBarry Smith SETERRQ1(PETSC_ERR_ARG_WRONGSTATE,"Need to set restriction or interpolation on level %d",(int)i); 450fccaa45eSBarry Smith } 451fccaa45eSBarry Smith #endif 452fccaa45eSBarry Smith } 4530a6bb862SBarry Smith for (i=0; i<n-1; i++) { 45437b0e6c0SBarry Smith if (!mg[i]->b) { 455906ed7ccSBarry Smith Vec *vec; 456906ed7ccSBarry Smith ierr = KSPGetVecs(mg[i]->smoothd,1,&vec,0,PETSC_NULL);CHKERRQ(ierr); 457906ed7ccSBarry Smith ierr = PCMGSetRhs(pc,i,*vec);CHKERRQ(ierr); 458906ed7ccSBarry Smith ierr = PetscFree(vec);CHKERRQ(ierr); 45937b0e6c0SBarry Smith } 4606ca4d86aSHong Zhang if (!mg[i]->r && i) { 4610a6bb862SBarry Smith ierr = VecDuplicate(mg[i]->b,&tvec);CHKERRQ(ierr); 46297177400SBarry Smith ierr = PCMGSetR(pc,i,tvec);CHKERRQ(ierr); 4630a6bb862SBarry Smith ierr = VecDestroy(tvec);CHKERRQ(ierr); 4640a6bb862SBarry Smith } 4650a6bb862SBarry Smith if (!mg[i]->x) { 4660a6bb862SBarry Smith ierr = VecDuplicate(mg[i]->b,&tvec);CHKERRQ(ierr); 46797177400SBarry Smith ierr = PCMGSetX(pc,i,tvec);CHKERRQ(ierr); 4680a6bb862SBarry Smith ierr = VecDestroy(tvec);CHKERRQ(ierr); 4690a6bb862SBarry Smith } 4700a6bb862SBarry Smith } 471*dfef70bdSHong Zhang if (n != 1 && !mg[n-1]->r) { 472*dfef70bdSHong Zhang /* PCMGSetR() on the finest level if user did not supply it */ 4730f77fa87SBarry Smith Vec *vec; 4740f77fa87SBarry Smith ierr = KSPGetVecs(mg[n-1]->smoothd,1,&vec,0,PETSC_NULL);CHKERRQ(ierr); 4750f77fa87SBarry Smith ierr = PCMGSetR(pc,n-1,*vec);CHKERRQ(ierr); 4760f77fa87SBarry Smith ierr = PetscFree(vec);CHKERRQ(ierr); 4770f77fa87SBarry Smith } 4784b9ad928SBarry Smith } 4794b9ad928SBarry Smith 480c2be2410SBarry Smith 4814b9ad928SBarry Smith for (i=1; i<n; i++) { 482b03c7568SBarry Smith if (mg[i]->smoothu == mg[i]->smoothd) { 483b03c7568SBarry Smith /* if doing only down then initial guess is zero */ 4844b9ad928SBarry Smith ierr = KSPSetInitialGuessNonzero(mg[i]->smoothd,PETSC_TRUE);CHKERRQ(ierr); 485b03c7568SBarry Smith } 48632cf1786SBarry Smith if (mg[i]->eventsmoothsetup) {ierr = PetscLogEventBegin(mg[i]->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} 4874b9ad928SBarry Smith ierr = KSPSetUp(mg[i]->smoothd);CHKERRQ(ierr); 48832cf1786SBarry Smith if (mg[i]->eventsmoothsetup) {ierr = PetscLogEventEnd(mg[i]->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} 4894b9ad928SBarry Smith } 490b03c7568SBarry Smith for (i=1; i<n; i++) { 4914b9ad928SBarry Smith if (mg[i]->smoothu && mg[i]->smoothu != mg[i]->smoothd) { 492906ed7ccSBarry Smith Mat downmat,downpmat; 49397f1f81fSBarry Smith MatStructure matflag; 494906ed7ccSBarry Smith PetscTruth opsset; 49597f1f81fSBarry Smith 49697f1f81fSBarry Smith /* check if operators have been set for up, if not use down operators to set them */ 497906ed7ccSBarry Smith ierr = KSPGetOperatorsSet(mg[i]->smoothu,&opsset,PETSC_NULL);CHKERRQ(ierr); 498906ed7ccSBarry Smith if (!opsset) { 499906ed7ccSBarry Smith ierr = KSPGetOperators(mg[i]->smoothd,&downmat,&downpmat,&matflag);CHKERRQ(ierr); 50097f1f81fSBarry Smith ierr = KSPSetOperators(mg[i]->smoothu,downmat,downpmat,matflag);CHKERRQ(ierr); 50197f1f81fSBarry Smith } 50297f1f81fSBarry Smith 5034b9ad928SBarry Smith ierr = KSPSetInitialGuessNonzero(mg[i]->smoothu,PETSC_TRUE);CHKERRQ(ierr); 50432cf1786SBarry Smith if (mg[i]->eventsmoothsetup) {ierr = PetscLogEventBegin(mg[i]->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} 5054b9ad928SBarry Smith ierr = KSPSetUp(mg[i]->smoothu);CHKERRQ(ierr); 50632cf1786SBarry Smith if (mg[i]->eventsmoothsetup) {ierr = PetscLogEventEnd(mg[i]->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} 5074b9ad928SBarry Smith } 5084b9ad928SBarry Smith } 5094b9ad928SBarry Smith 5104b9ad928SBarry Smith /* 5114b9ad928SBarry Smith If coarse solver is not direct method then DO NOT USE preonly 5124b9ad928SBarry Smith */ 5134b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)mg[0]->smoothd,KSPPREONLY,&preonly);CHKERRQ(ierr); 5144b9ad928SBarry Smith if (preonly) { 5154b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)cpc,PCLU,&lu);CHKERRQ(ierr); 5164b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)cpc,PCREDUNDANT,&redundant);CHKERRQ(ierr); 51768eff7e6SBarry Smith ierr = PetscTypeCompare((PetscObject)cpc,PCCHOLESKY,&cholesky);CHKERRQ(ierr); 51868eff7e6SBarry Smith if (!lu && !redundant && !cholesky) { 5194b9ad928SBarry Smith ierr = KSPSetType(mg[0]->smoothd,KSPGMRES);CHKERRQ(ierr); 5204b9ad928SBarry Smith } 5214b9ad928SBarry Smith } 5224b9ad928SBarry Smith 523958c9bccSBarry Smith if (!pc->setupcalled) { 5244b9ad928SBarry Smith if (monitor) { 5254b9ad928SBarry Smith ierr = PetscObjectGetComm((PetscObject)mg[0]->smoothd,&comm);CHKERRQ(ierr); 52623d894e5SBarry Smith ierr = PetscViewerASCIIMonitorCreate(comm,"stdout",n,&ascii);CHKERRQ(ierr); 52723d894e5SBarry Smith ierr = KSPMonitorSet(mg[0]->smoothd,KSPMonitorDefault,ascii,(PetscErrorCode(*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 5284b9ad928SBarry Smith } 5294b9ad928SBarry Smith ierr = KSPSetFromOptions(mg[0]->smoothd);CHKERRQ(ierr); 5304b9ad928SBarry Smith } 5314b9ad928SBarry Smith 53232cf1786SBarry Smith if (mg[0]->eventsmoothsetup) {ierr = PetscLogEventBegin(mg[0]->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} 5334b9ad928SBarry Smith ierr = KSPSetUp(mg[0]->smoothd);CHKERRQ(ierr); 53432cf1786SBarry Smith if (mg[0]->eventsmoothsetup) {ierr = PetscLogEventEnd(mg[0]->eventsmoothsetup,0,0,0,0);CHKERRQ(ierr);} 5354b9ad928SBarry Smith 5364b9ad928SBarry Smith /* 5376805f65bSBarry Smith Dump the interpolation/restriction matrices plus the 5384b9ad928SBarry Smith Jacobian/stiffness on each level. This allows Matlab users to 5396805f65bSBarry Smith easily check if the Galerkin condition A_c = R A_f R^T is satisfied. 5406805f65bSBarry Smith 5416805f65bSBarry Smith Only support one or the other at the same time. 5426805f65bSBarry Smith */ 5436805f65bSBarry Smith #if defined(PETSC_USE_SOCKET_VIEWER) 5447adad957SLisandro Dalcin ierr = PetscOptionsHasName(((PetscObject)pc)->prefix,"-pc_mg_dump_matlab",&dump);CHKERRQ(ierr); 5454b9ad928SBarry Smith if (dump) { 5467adad957SLisandro Dalcin viewer = PETSC_VIEWER_SOCKET_(((PetscObject)pc)->comm); 5474b9ad928SBarry Smith } 548c45a1595SBarry Smith #endif 5497adad957SLisandro Dalcin ierr = PetscOptionsHasName(((PetscObject)pc)->prefix,"-pc_mg_dump_binary",&dump);CHKERRQ(ierr); 550c2be2410SBarry Smith if (dump) { 5517adad957SLisandro Dalcin viewer = PETSC_VIEWER_BINARY_(((PetscObject)pc)->comm); 5526805f65bSBarry Smith } 5536805f65bSBarry Smith 5546805f65bSBarry Smith if (viewer) { 555c2be2410SBarry Smith for (i=1; i<n; i++) { 5566805f65bSBarry Smith ierr = MatView(mg[i]->restrct,viewer);CHKERRQ(ierr); 557c2be2410SBarry Smith } 558c2be2410SBarry Smith for (i=0; i<n; i++) { 559c2be2410SBarry Smith ierr = KSPGetPC(mg[i]->smoothd,&pc);CHKERRQ(ierr); 5606805f65bSBarry Smith ierr = MatView(pc->mat,viewer);CHKERRQ(ierr); 561c2be2410SBarry Smith } 562c2be2410SBarry Smith } 5634b9ad928SBarry Smith PetscFunctionReturn(0); 5644b9ad928SBarry Smith } 5654b9ad928SBarry Smith 5664b9ad928SBarry Smith /* -------------------------------------------------------------------------------------*/ 5674b9ad928SBarry Smith 5684b9ad928SBarry Smith #undef __FUNCT__ 5699dcbbd2bSBarry Smith #define __FUNCT__ "PCMGSetLevels" 5704b9ad928SBarry Smith /*@C 57197177400SBarry Smith PCMGSetLevels - Sets the number of levels to use with MG. 5724b9ad928SBarry Smith Must be called before any other MG routine. 5734b9ad928SBarry Smith 5744b9ad928SBarry Smith Collective on PC 5754b9ad928SBarry Smith 5764b9ad928SBarry Smith Input Parameters: 5774b9ad928SBarry Smith + pc - the preconditioner context 5784b9ad928SBarry Smith . levels - the number of levels 5794b9ad928SBarry Smith - comms - optional communicators for each level; this is to allow solving the coarser problems 5804b9ad928SBarry Smith on smaller sets of processors. Use PETSC_NULL_OBJECT for default in Fortran 5814b9ad928SBarry Smith 5824b9ad928SBarry Smith Level: intermediate 5834b9ad928SBarry Smith 5844b9ad928SBarry Smith Notes: 5854b9ad928SBarry Smith If the number of levels is one then the multigrid uses the -mg_levels prefix 5864b9ad928SBarry Smith for setting the level options rather than the -mg_coarse prefix. 5874b9ad928SBarry Smith 5884b9ad928SBarry Smith .keywords: MG, set, levels, multigrid 5894b9ad928SBarry Smith 59097177400SBarry Smith .seealso: PCMGSetType(), PCMGGetLevels() 5914b9ad928SBarry Smith @*/ 59297177400SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetLevels(PC pc,PetscInt levels,MPI_Comm *comms) 5934b9ad928SBarry Smith { 594dfbe8321SBarry Smith PetscErrorCode ierr; 595ada7143aSSatish Balay PC_MG **mg=0; 5964b9ad928SBarry Smith 5974b9ad928SBarry Smith PetscFunctionBegin; 5984482741eSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 5994b9ad928SBarry Smith 6004b9ad928SBarry Smith if (pc->data) { 6011302d50aSBarry Smith SETERRQ(PETSC_ERR_ORDER,"Number levels already set for MG\n\ 60297177400SBarry Smith make sure that you call PCMGSetLevels() before KSPSetFromOptions()"); 6034b9ad928SBarry Smith } 6047adad957SLisandro Dalcin ierr = PCMGCreate_Private(((PetscObject)pc)->comm,levels,pc,comms,&mg);CHKERRQ(ierr); 6059dcbbd2bSBarry Smith mg[0]->am = PC_MG_MULTIPLICATIVE; 6064b9ad928SBarry Smith pc->data = (void*)mg; 6074b9ad928SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_MG; 6084b9ad928SBarry Smith PetscFunctionReturn(0); 6094b9ad928SBarry Smith } 6104b9ad928SBarry Smith 6114b9ad928SBarry Smith #undef __FUNCT__ 6129dcbbd2bSBarry Smith #define __FUNCT__ "PCMGGetLevels" 6134b9ad928SBarry Smith /*@ 61497177400SBarry Smith PCMGGetLevels - Gets the number of levels to use with MG. 6154b9ad928SBarry Smith 6164b9ad928SBarry Smith Not Collective 6174b9ad928SBarry Smith 6184b9ad928SBarry Smith Input Parameter: 6194b9ad928SBarry Smith . pc - the preconditioner context 6204b9ad928SBarry Smith 6214b9ad928SBarry Smith Output parameter: 6224b9ad928SBarry Smith . levels - the number of levels 6234b9ad928SBarry Smith 6244b9ad928SBarry Smith Level: advanced 6254b9ad928SBarry Smith 6264b9ad928SBarry Smith .keywords: MG, get, levels, multigrid 6274b9ad928SBarry Smith 62897177400SBarry Smith .seealso: PCMGSetLevels() 6294b9ad928SBarry Smith @*/ 63097177400SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGGetLevels(PC pc,PetscInt *levels) 6314b9ad928SBarry Smith { 6329dcbbd2bSBarry Smith PC_MG **mg; 6334b9ad928SBarry Smith 6344b9ad928SBarry Smith PetscFunctionBegin; 6354482741eSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 6364482741eSBarry Smith PetscValidIntPointer(levels,2); 6374b9ad928SBarry Smith 6389dcbbd2bSBarry Smith mg = (PC_MG**)pc->data; 6394b9ad928SBarry Smith *levels = mg[0]->levels; 6404b9ad928SBarry Smith PetscFunctionReturn(0); 6414b9ad928SBarry Smith } 6424b9ad928SBarry Smith 6434b9ad928SBarry Smith #undef __FUNCT__ 6449dcbbd2bSBarry Smith #define __FUNCT__ "PCMGSetType" 6454b9ad928SBarry Smith /*@ 64697177400SBarry Smith PCMGSetType - Determines the form of multigrid to use: 6474b9ad928SBarry Smith multiplicative, additive, full, or the Kaskade algorithm. 6484b9ad928SBarry Smith 6494b9ad928SBarry Smith Collective on PC 6504b9ad928SBarry Smith 6514b9ad928SBarry Smith Input Parameters: 6524b9ad928SBarry Smith + pc - the preconditioner context 6539dcbbd2bSBarry Smith - form - multigrid form, one of PC_MG_MULTIPLICATIVE, PC_MG_ADDITIVE, 6549dcbbd2bSBarry Smith PC_MG_FULL, PC_MG_KASKADE 6554b9ad928SBarry Smith 6564b9ad928SBarry Smith Options Database Key: 6574b9ad928SBarry Smith . -pc_mg_type <form> - Sets <form>, one of multiplicative, 6584b9ad928SBarry Smith additive, full, kaskade 6594b9ad928SBarry Smith 6604b9ad928SBarry Smith Level: advanced 6614b9ad928SBarry Smith 6624b9ad928SBarry Smith .keywords: MG, set, method, multiplicative, additive, full, Kaskade, multigrid 6634b9ad928SBarry Smith 66497177400SBarry Smith .seealso: PCMGSetLevels() 6654b9ad928SBarry Smith @*/ 6669dcbbd2bSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetType(PC pc,PCMGType form) 6674b9ad928SBarry Smith { 6689dcbbd2bSBarry Smith PC_MG **mg; 6694b9ad928SBarry Smith 6704b9ad928SBarry Smith PetscFunctionBegin; 6714482741eSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 6729dcbbd2bSBarry Smith mg = (PC_MG**)pc->data; 6734b9ad928SBarry Smith 6744b9ad928SBarry Smith if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 6754b9ad928SBarry Smith mg[0]->am = form; 6769dcbbd2bSBarry Smith if (form == PC_MG_MULTIPLICATIVE) pc->ops->applyrichardson = PCApplyRichardson_MG; 6774b9ad928SBarry Smith else pc->ops->applyrichardson = 0; 6784b9ad928SBarry Smith PetscFunctionReturn(0); 6794b9ad928SBarry Smith } 6804b9ad928SBarry Smith 6814b9ad928SBarry Smith #undef __FUNCT__ 6820d353602SBarry Smith #define __FUNCT__ "PCMGSetCycleType" 6834b9ad928SBarry Smith /*@ 6840d353602SBarry Smith PCMGSetCycleType - Sets the type cycles to use. Use PCMGSetCycleTypeOnLevel() for more 6854b9ad928SBarry Smith complicated cycling. 6864b9ad928SBarry Smith 6874b9ad928SBarry Smith Collective on PC 6884b9ad928SBarry Smith 6894b9ad928SBarry Smith Input Parameters: 690c2be2410SBarry Smith + pc - the multigrid context 6910d353602SBarry Smith - PC_MG_CYCLE_V or PC_MG_CYCLE_W 6924b9ad928SBarry Smith 6934b9ad928SBarry Smith Options Database Key: 6940d353602SBarry Smith $ -pc_mg_cycle_type v or w 6954b9ad928SBarry Smith 6964b9ad928SBarry Smith Level: advanced 6974b9ad928SBarry Smith 6984b9ad928SBarry Smith .keywords: MG, set, cycles, V-cycle, W-cycle, multigrid 6994b9ad928SBarry Smith 7000d353602SBarry Smith .seealso: PCMGSetCycleTypeOnLevel() 7014b9ad928SBarry Smith @*/ 7020d353602SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetCycleType(PC pc,PCMGCycleType n) 7034b9ad928SBarry Smith { 7049dcbbd2bSBarry Smith PC_MG **mg; 70579416396SBarry Smith PetscInt i,levels; 7064b9ad928SBarry Smith 7074b9ad928SBarry Smith PetscFunctionBegin; 7084482741eSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 7099dcbbd2bSBarry Smith mg = (PC_MG**)pc->data; 7104b9ad928SBarry Smith if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 7114b9ad928SBarry Smith levels = mg[0]->levels; 7124b9ad928SBarry Smith 7134b9ad928SBarry Smith for (i=0; i<levels; i++) { 7144b9ad928SBarry Smith mg[i]->cycles = n; 7154b9ad928SBarry Smith } 7164b9ad928SBarry Smith PetscFunctionReturn(0); 7174b9ad928SBarry Smith } 7184b9ad928SBarry Smith 7194b9ad928SBarry Smith #undef __FUNCT__ 7208cc2d5dfSBarry Smith #define __FUNCT__ "PCMGMultiplicativeSetCycles" 7218cc2d5dfSBarry Smith /*@ 7228cc2d5dfSBarry Smith PCMGMultiplicativeSetCycles - Sets the number of cycles to use for each preconditioner step 7238cc2d5dfSBarry Smith of multigrid when PCMGType of PC_MG_MULTIPLICATIVE is used 7248cc2d5dfSBarry Smith 7258cc2d5dfSBarry Smith Collective on PC 7268cc2d5dfSBarry Smith 7278cc2d5dfSBarry Smith Input Parameters: 7288cc2d5dfSBarry Smith + pc - the multigrid context 7298cc2d5dfSBarry Smith - n - number of cycles (default is 1) 7308cc2d5dfSBarry Smith 7318cc2d5dfSBarry Smith Options Database Key: 7328cc2d5dfSBarry Smith $ -pc_mg_multiplicative_cycles n 7338cc2d5dfSBarry Smith 7348cc2d5dfSBarry Smith Level: advanced 7358cc2d5dfSBarry Smith 7368cc2d5dfSBarry Smith Notes: This is not associated with setting a v or w cycle, that is set with PCMGSetCycleType() 7378cc2d5dfSBarry Smith 7388cc2d5dfSBarry Smith .keywords: MG, set, cycles, V-cycle, W-cycle, multigrid 7398cc2d5dfSBarry Smith 7408cc2d5dfSBarry Smith .seealso: PCMGSetCycleTypeOnLevel(), PCMGSetCycleType() 7418cc2d5dfSBarry Smith @*/ 7428cc2d5dfSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGMultiplicativeSetCycles(PC pc,PetscInt n) 7438cc2d5dfSBarry Smith { 7448cc2d5dfSBarry Smith PC_MG **mg; 7458cc2d5dfSBarry Smith PetscInt i,levels; 7468cc2d5dfSBarry Smith 7478cc2d5dfSBarry Smith PetscFunctionBegin; 7488cc2d5dfSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 7498cc2d5dfSBarry Smith mg = (PC_MG**)pc->data; 7508cc2d5dfSBarry Smith if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 7518cc2d5dfSBarry Smith levels = mg[0]->levels; 7528cc2d5dfSBarry Smith 7538cc2d5dfSBarry Smith for (i=0; i<levels; i++) { 7548cc2d5dfSBarry Smith mg[i]->cyclesperpcapply = n; 7558cc2d5dfSBarry Smith } 7568cc2d5dfSBarry Smith PetscFunctionReturn(0); 7578cc2d5dfSBarry Smith } 7588cc2d5dfSBarry Smith 7598cc2d5dfSBarry Smith #undef __FUNCT__ 7609dcbbd2bSBarry Smith #define __FUNCT__ "PCMGSetGalerkin" 761c2be2410SBarry Smith /*@ 76297177400SBarry Smith PCMGSetGalerkin - Causes the coarser grid matrices to be computed from the 763c2be2410SBarry Smith finest grid via the Galerkin process: A_i-1 = r_i * A_i * r_i^t 764c2be2410SBarry Smith 765c2be2410SBarry Smith Collective on PC 766c2be2410SBarry Smith 767c2be2410SBarry Smith Input Parameters: 7683fc8bf9cSBarry Smith . pc - the multigrid context 769c2be2410SBarry Smith 770c2be2410SBarry Smith Options Database Key: 771c2be2410SBarry Smith $ -pc_mg_galerkin 772c2be2410SBarry Smith 773c2be2410SBarry Smith Level: intermediate 774c2be2410SBarry Smith 775c2be2410SBarry Smith .keywords: MG, set, Galerkin 776c2be2410SBarry Smith 7773fc8bf9cSBarry Smith .seealso: PCMGGetGalerkin() 7783fc8bf9cSBarry Smith 779c2be2410SBarry Smith @*/ 78097177400SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetGalerkin(PC pc) 781c2be2410SBarry Smith { 7829dcbbd2bSBarry Smith PC_MG **mg; 783c2be2410SBarry Smith PetscInt i,levels; 784c2be2410SBarry Smith 785c2be2410SBarry Smith PetscFunctionBegin; 786c2be2410SBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 7879dcbbd2bSBarry Smith mg = (PC_MG**)pc->data; 788c2be2410SBarry Smith if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 789c2be2410SBarry Smith levels = mg[0]->levels; 790c2be2410SBarry Smith 791c2be2410SBarry Smith for (i=0; i<levels; i++) { 792c2be2410SBarry Smith mg[i]->galerkin = PETSC_TRUE; 793c2be2410SBarry Smith } 794c2be2410SBarry Smith PetscFunctionReturn(0); 795c2be2410SBarry Smith } 796c2be2410SBarry Smith 797c2be2410SBarry Smith #undef __FUNCT__ 7983fc8bf9cSBarry Smith #define __FUNCT__ "PCMGGetGalerkin" 7993fc8bf9cSBarry Smith /*@ 8003fc8bf9cSBarry Smith PCMGGetGalerkin - Checks if Galerkin multigrid is being used, i.e. 8013fc8bf9cSBarry Smith A_i-1 = r_i * A_i * r_i^t 8023fc8bf9cSBarry Smith 8033fc8bf9cSBarry Smith Not Collective 8043fc8bf9cSBarry Smith 8053fc8bf9cSBarry Smith Input Parameter: 8063fc8bf9cSBarry Smith . pc - the multigrid context 8073fc8bf9cSBarry Smith 8083fc8bf9cSBarry Smith Output Parameter: 8093fc8bf9cSBarry Smith . gelerkin - PETSC_TRUE or PETSC_FALSE 8103fc8bf9cSBarry Smith 8113fc8bf9cSBarry Smith Options Database Key: 8123fc8bf9cSBarry Smith $ -pc_mg_galerkin 8133fc8bf9cSBarry Smith 8143fc8bf9cSBarry Smith Level: intermediate 8153fc8bf9cSBarry Smith 8163fc8bf9cSBarry Smith .keywords: MG, set, Galerkin 8173fc8bf9cSBarry Smith 8183fc8bf9cSBarry Smith .seealso: PCMGSetGalerkin() 8193fc8bf9cSBarry Smith 8203fc8bf9cSBarry Smith @*/ 8213fc8bf9cSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGGetGalerkin(PC pc,PetscTruth *galerkin) 8223fc8bf9cSBarry Smith { 8233fc8bf9cSBarry Smith PC_MG **mg; 8243fc8bf9cSBarry Smith 8253fc8bf9cSBarry Smith PetscFunctionBegin; 8263fc8bf9cSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 8273fc8bf9cSBarry Smith mg = (PC_MG**)pc->data; 8283fc8bf9cSBarry Smith if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 8293fc8bf9cSBarry Smith *galerkin = mg[0]->galerkin; 8303fc8bf9cSBarry Smith PetscFunctionReturn(0); 8313fc8bf9cSBarry Smith } 8323fc8bf9cSBarry Smith 8333fc8bf9cSBarry Smith #undef __FUNCT__ 8349dcbbd2bSBarry Smith #define __FUNCT__ "PCMGSetNumberSmoothDown" 8354b9ad928SBarry Smith /*@ 83697177400SBarry Smith PCMGSetNumberSmoothDown - Sets the number of pre-smoothing steps to 83797177400SBarry Smith use on all levels. Use PCMGGetSmootherDown() to set different 8384b9ad928SBarry Smith pre-smoothing steps on different levels. 8394b9ad928SBarry Smith 8404b9ad928SBarry Smith Collective on PC 8414b9ad928SBarry Smith 8424b9ad928SBarry Smith Input Parameters: 8434b9ad928SBarry Smith + mg - the multigrid context 8444b9ad928SBarry Smith - n - the number of smoothing steps 8454b9ad928SBarry Smith 8464b9ad928SBarry Smith Options Database Key: 8474b9ad928SBarry Smith . -pc_mg_smoothdown <n> - Sets number of pre-smoothing steps 8484b9ad928SBarry Smith 8494b9ad928SBarry Smith Level: advanced 8504b9ad928SBarry Smith 8514b9ad928SBarry Smith .keywords: MG, smooth, down, pre-smoothing, steps, multigrid 8524b9ad928SBarry Smith 85397177400SBarry Smith .seealso: PCMGSetNumberSmoothUp() 8544b9ad928SBarry Smith @*/ 85597177400SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetNumberSmoothDown(PC pc,PetscInt n) 8564b9ad928SBarry Smith { 8579dcbbd2bSBarry Smith PC_MG **mg; 8586849ba73SBarry Smith PetscErrorCode ierr; 85979416396SBarry Smith PetscInt i,levels; 8604b9ad928SBarry Smith 8614b9ad928SBarry Smith PetscFunctionBegin; 8624482741eSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 8639dcbbd2bSBarry Smith mg = (PC_MG**)pc->data; 8644b9ad928SBarry Smith if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 8654b9ad928SBarry Smith levels = mg[0]->levels; 8664b9ad928SBarry Smith 867b05257ddSBarry Smith for (i=1; i<levels; i++) { 8684b9ad928SBarry Smith /* make sure smoother up and down are different */ 86997177400SBarry Smith ierr = PCMGGetSmootherUp(pc,i,PETSC_NULL);CHKERRQ(ierr); 8704b9ad928SBarry Smith ierr = KSPSetTolerances(mg[i]->smoothd,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,n);CHKERRQ(ierr); 8714b9ad928SBarry Smith mg[i]->default_smoothd = n; 8724b9ad928SBarry Smith } 8734b9ad928SBarry Smith PetscFunctionReturn(0); 8744b9ad928SBarry Smith } 8754b9ad928SBarry Smith 8764b9ad928SBarry Smith #undef __FUNCT__ 8779dcbbd2bSBarry Smith #define __FUNCT__ "PCMGSetNumberSmoothUp" 8784b9ad928SBarry Smith /*@ 87997177400SBarry Smith PCMGSetNumberSmoothUp - Sets the number of post-smoothing steps to use 88097177400SBarry Smith on all levels. Use PCMGGetSmootherUp() to set different numbers of 8814b9ad928SBarry Smith post-smoothing steps on different levels. 8824b9ad928SBarry Smith 8834b9ad928SBarry Smith Collective on PC 8844b9ad928SBarry Smith 8854b9ad928SBarry Smith Input Parameters: 8864b9ad928SBarry Smith + mg - the multigrid context 8874b9ad928SBarry Smith - n - the number of smoothing steps 8884b9ad928SBarry Smith 8894b9ad928SBarry Smith Options Database Key: 8904b9ad928SBarry Smith . -pc_mg_smoothup <n> - Sets number of post-smoothing steps 8914b9ad928SBarry Smith 8924b9ad928SBarry Smith Level: advanced 8934b9ad928SBarry Smith 8944b9ad928SBarry Smith Note: this does not set a value on the coarsest grid, since we assume that 895a8c7a070SBarry Smith there is no separate smooth up on the coarsest grid. 8964b9ad928SBarry Smith 8974b9ad928SBarry Smith .keywords: MG, smooth, up, post-smoothing, steps, multigrid 8984b9ad928SBarry Smith 89997177400SBarry Smith .seealso: PCMGSetNumberSmoothDown() 9004b9ad928SBarry Smith @*/ 90197177400SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetNumberSmoothUp(PC pc,PetscInt n) 9024b9ad928SBarry Smith { 9039dcbbd2bSBarry Smith PC_MG **mg; 9046849ba73SBarry Smith PetscErrorCode ierr; 90579416396SBarry Smith PetscInt i,levels; 9064b9ad928SBarry Smith 9074b9ad928SBarry Smith PetscFunctionBegin; 9084482741eSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 9099dcbbd2bSBarry Smith mg = (PC_MG**)pc->data; 9104b9ad928SBarry Smith if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 9114b9ad928SBarry Smith levels = mg[0]->levels; 9124b9ad928SBarry Smith 9134b9ad928SBarry Smith for (i=1; i<levels; i++) { 9144b9ad928SBarry Smith /* make sure smoother up and down are different */ 91597177400SBarry Smith ierr = PCMGGetSmootherUp(pc,i,PETSC_NULL);CHKERRQ(ierr); 9164b9ad928SBarry Smith ierr = KSPSetTolerances(mg[i]->smoothu,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,n);CHKERRQ(ierr); 9174b9ad928SBarry Smith mg[i]->default_smoothu = n; 9184b9ad928SBarry Smith } 9194b9ad928SBarry Smith PetscFunctionReturn(0); 9204b9ad928SBarry Smith } 9214b9ad928SBarry Smith 9224b9ad928SBarry Smith /* ----------------------------------------------------------------------------------------*/ 9234b9ad928SBarry Smith 9243b09bd56SBarry Smith /*MC 925ccb205f8SBarry Smith PCMG - Use multigrid preconditioning. This preconditioner requires you provide additional 9263b09bd56SBarry Smith information about the coarser grid matrices and restriction/interpolation operators. 9273b09bd56SBarry Smith 9283b09bd56SBarry Smith Options Database Keys: 9293b09bd56SBarry Smith + -pc_mg_levels <nlevels> - number of levels including finest 9300d353602SBarry Smith . -pc_mg_cycles v or w 93179416396SBarry Smith . -pc_mg_smoothup <n> - number of smoothing steps after interpolation 9323b09bd56SBarry Smith . -pc_mg_smoothdown <n> - number of smoothing steps before applying restriction operator 9333b09bd56SBarry Smith . -pc_mg_type <additive,multiplicative,full,cascade> - multiplicative is the default 9343b09bd56SBarry Smith . -pc_mg_log - log information about time spent on each level of the solver 9353b09bd56SBarry Smith . -pc_mg_monitor - print information on the multigrid convergence 93668eff7e6SBarry Smith . -pc_mg_galerkin - use Galerkin process to compute coarser operators 9373b09bd56SBarry Smith - -pc_mg_dump_matlab - dumps the matrices for each level and the restriction/interpolation matrices 9383b09bd56SBarry Smith to the Socket viewer for reading from Matlab. 9393b09bd56SBarry Smith 9403b09bd56SBarry Smith Notes: 9413b09bd56SBarry Smith 9423b09bd56SBarry Smith Level: intermediate 9433b09bd56SBarry Smith 9448f87f92bSBarry Smith Concepts: multigrid/multilevel 9453b09bd56SBarry Smith 9463b09bd56SBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, PCMGType, 9470d353602SBarry Smith PCMGSetLevels(), PCMGGetLevels(), PCMGSetType(), PCMGSetCycleType(), PCMGSetNumberSmoothDown(), 94897177400SBarry Smith PCMGSetNumberSmoothUp(), PCMGGetCoarseSolve(), PCMGSetResidual(), PCMGSetInterpolation(), 94997177400SBarry Smith PCMGSetRestriction(), PCMGGetSmoother(), PCMGGetSmootherUp(), PCMGGetSmootherDown(), 9500d353602SBarry Smith PCMGSetCycleTypeOnLevel(), PCMGSetRhs(), PCMGSetX(), PCMGSetR() 9513b09bd56SBarry Smith M*/ 9523b09bd56SBarry Smith 9534b9ad928SBarry Smith EXTERN_C_BEGIN 9544b9ad928SBarry Smith #undef __FUNCT__ 9554b9ad928SBarry Smith #define __FUNCT__ "PCCreate_MG" 956dba47a55SKris Buschelman PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_MG(PC pc) 9574b9ad928SBarry Smith { 9584b9ad928SBarry Smith PetscFunctionBegin; 9594b9ad928SBarry Smith pc->ops->apply = PCApply_MG; 9604b9ad928SBarry Smith pc->ops->setup = PCSetUp_MG; 9614b9ad928SBarry Smith pc->ops->destroy = PCDestroy_MG; 9624b9ad928SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_MG; 9634b9ad928SBarry Smith pc->ops->view = PCView_MG; 9644b9ad928SBarry Smith 9654b9ad928SBarry Smith pc->data = (void*)0; 9664b9ad928SBarry Smith PetscFunctionReturn(0); 9674b9ad928SBarry Smith } 9684b9ad928SBarry Smith EXTERN_C_END 969