14b9ad928SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/pcmgimpl.h> /*I "petscksp.h" I*/ 34b9ad928SBarry Smith 4f9426fe0SMark Adams /* ---------------------------------------------------------------------------*/ 51f6cc5b2SSatish Balay /*@C 654b2cd4bSJed Brown PCMGResidualDefault - Default routine to calculate the residual. 74b9ad928SBarry Smith 84b9ad928SBarry Smith Collective on Mat and Vec 94b9ad928SBarry Smith 104b9ad928SBarry Smith Input Parameters: 114b9ad928SBarry Smith + mat - the matrix 124b9ad928SBarry Smith . b - the right-hand-side 134b9ad928SBarry Smith - x - the approximate solution 144b9ad928SBarry Smith 154b9ad928SBarry Smith Output Parameter: 164b9ad928SBarry Smith . r - location to store the residual 174b9ad928SBarry Smith 18d0e4de75SBarry Smith Level: developer 194b9ad928SBarry Smith 204b9ad928SBarry Smith .keywords: MG, default, multigrid, residual 214b9ad928SBarry Smith 2297177400SBarry Smith .seealso: PCMGSetResidual() 234b9ad928SBarry Smith @*/ 2454b2cd4bSJed Brown PetscErrorCode PCMGResidualDefault(Mat mat,Vec b,Vec x,Vec r) 254b9ad928SBarry Smith { 26dfbe8321SBarry Smith PetscErrorCode ierr; 274b9ad928SBarry Smith 284b9ad928SBarry Smith PetscFunctionBegin; 29f9426fe0SMark Adams ierr = MatResidual(mat,b,x,r);CHKERRQ(ierr); 304b9ad928SBarry Smith PetscFunctionReturn(0); 314b9ad928SBarry Smith } 324b9ad928SBarry Smith 33f39d8e23SSatish Balay /*@ 3497177400SBarry Smith PCMGGetCoarseSolve - Gets the solver context to be used on the coarse grid. 354b9ad928SBarry Smith 364b9ad928SBarry Smith Not Collective 374b9ad928SBarry Smith 384b9ad928SBarry Smith Input Parameter: 394b9ad928SBarry Smith . pc - the multigrid context 404b9ad928SBarry Smith 414b9ad928SBarry Smith Output Parameter: 424b9ad928SBarry Smith . ksp - the coarse grid solver context 434b9ad928SBarry Smith 444b9ad928SBarry Smith Level: advanced 454b9ad928SBarry Smith 464b9ad928SBarry Smith .keywords: MG, multigrid, get, coarse grid 474b9ad928SBarry Smith @*/ 487087cfbeSBarry Smith PetscErrorCode PCMGGetCoarseSolve(PC pc,KSP *ksp) 494b9ad928SBarry Smith { 50f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 51f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 524b9ad928SBarry Smith 534b9ad928SBarry Smith PetscFunctionBegin; 54c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 55f3fbd535SBarry Smith *ksp = mglevels[0]->smoothd; 564b9ad928SBarry Smith PetscFunctionReturn(0); 574b9ad928SBarry Smith } 584b9ad928SBarry Smith 594b9ad928SBarry Smith /*@C 6097177400SBarry Smith PCMGSetResidual - Sets the function to be used to calculate the residual 614b9ad928SBarry Smith on the lth level. 624b9ad928SBarry Smith 63ad4df100SBarry Smith Logically Collective on PC and Mat 644b9ad928SBarry Smith 654b9ad928SBarry Smith Input Parameters: 664b9ad928SBarry Smith + pc - the multigrid context 674b9ad928SBarry Smith . l - the level (0 is coarsest) to supply 68157726a2SBarry Smith . residual - function used to form residual, if none is provided the previously provide one is used, if no 69d0e4de75SBarry Smith previous one were provided then a default is used 704b9ad928SBarry Smith - mat - matrix associated with residual 714b9ad928SBarry Smith 724b9ad928SBarry Smith Level: advanced 734b9ad928SBarry Smith 744b9ad928SBarry Smith .keywords: MG, set, multigrid, residual, level 754b9ad928SBarry Smith 7654b2cd4bSJed Brown .seealso: PCMGResidualDefault() 774b9ad928SBarry Smith @*/ 787087cfbeSBarry Smith PetscErrorCode PCMGSetResidual(PC pc,PetscInt l,PetscErrorCode (*residual)(Mat,Vec,Vec,Vec),Mat mat) 794b9ad928SBarry Smith { 80f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 81f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 82298cc208SBarry Smith PetscErrorCode ierr; 834b9ad928SBarry Smith 844b9ad928SBarry Smith PetscFunctionBegin; 85c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 86ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 872fa5cd67SKarl Rupp if (residual) mglevels[l]->residual = residual; 8854b2cd4bSJed Brown if (!mglevels[l]->residual) mglevels[l]->residual = PCMGResidualDefault; 89f3ae41bdSBarry Smith if (mat) {ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);} 90298cc208SBarry Smith ierr = MatDestroy(&mglevels[l]->A);CHKERRQ(ierr); 91f3fbd535SBarry Smith mglevels[l]->A = mat; 924b9ad928SBarry Smith PetscFunctionReturn(0); 934b9ad928SBarry Smith } 944b9ad928SBarry Smith 954b9ad928SBarry Smith /*@ 96aea2a34eSBarry Smith PCMGSetInterpolation - Sets the function to be used to calculate the 97bf5b2e24SBarry Smith interpolation from l-1 to the lth level 984b9ad928SBarry Smith 99ad4df100SBarry Smith Logically Collective on PC and Mat 1004b9ad928SBarry Smith 1014b9ad928SBarry Smith Input Parameters: 1024b9ad928SBarry Smith + pc - the multigrid context 1034b9ad928SBarry Smith . mat - the interpolation operator 104bf5b2e24SBarry Smith - l - the level (0 is coarsest) to supply [do not supply 0] 1054b9ad928SBarry Smith 1064b9ad928SBarry Smith Level: advanced 1074b9ad928SBarry Smith 1084b9ad928SBarry Smith Notes: 1094b9ad928SBarry Smith Usually this is the same matrix used also to set the restriction 1104b9ad928SBarry Smith for the same level. 1114b9ad928SBarry Smith 1124b9ad928SBarry Smith One can pass in the interpolation matrix or its transpose; PETSc figures 1134b9ad928SBarry Smith out from the matrix size which one it is. 1144b9ad928SBarry Smith 1154b9ad928SBarry Smith .keywords: multigrid, set, interpolate, level 1164b9ad928SBarry Smith 11797177400SBarry Smith .seealso: PCMGSetRestriction() 1184b9ad928SBarry Smith @*/ 1197087cfbeSBarry Smith PetscErrorCode PCMGSetInterpolation(PC pc,PetscInt l,Mat mat) 1204b9ad928SBarry Smith { 121f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 122f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 123fccaa45eSBarry Smith PetscErrorCode ierr; 1244b9ad928SBarry Smith 1254b9ad928SBarry Smith PetscFunctionBegin; 126c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 127ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 128ce94432eSBarry Smith if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Do not set interpolation routine for coarsest level"); 129c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 1306bf464f9SBarry Smith ierr = MatDestroy(&mglevels[l]->interpolate);CHKERRQ(ierr); 1312fa5cd67SKarl Rupp 132f3fbd535SBarry Smith mglevels[l]->interpolate = mat; 1334b9ad928SBarry Smith PetscFunctionReturn(0); 1344b9ad928SBarry Smith } 1354b9ad928SBarry Smith 136c88c5224SJed Brown /*@ 137c88c5224SJed Brown PCMGGetInterpolation - Gets the function to be used to calculate the 138c88c5224SJed Brown interpolation from l-1 to the lth level 139c88c5224SJed Brown 140c88c5224SJed Brown Logically Collective on PC 141c88c5224SJed Brown 142c88c5224SJed Brown Input Parameters: 143c88c5224SJed Brown + pc - the multigrid context 144c88c5224SJed Brown - l - the level (0 is coarsest) to supply [Do not supply 0] 145c88c5224SJed Brown 146c88c5224SJed Brown Output Parameter: 1473ad4599aSBarry Smith . mat - the interpolation matrix, can be NULL 148c88c5224SJed Brown 149c88c5224SJed Brown Level: advanced 150c88c5224SJed Brown 151c88c5224SJed Brown .keywords: MG, get, multigrid, interpolation, level 152c88c5224SJed Brown 153c88c5224SJed Brown .seealso: PCMGGetRestriction(), PCMGSetInterpolation(), PCMGGetRScale() 154c88c5224SJed Brown @*/ 155c88c5224SJed Brown PetscErrorCode PCMGGetInterpolation(PC pc,PetscInt l,Mat *mat) 156c88c5224SJed Brown { 157c88c5224SJed Brown PC_MG *mg = (PC_MG*)pc->data; 158c88c5224SJed Brown PC_MG_Levels **mglevels = mg->levels; 159c88c5224SJed Brown PetscErrorCode ierr; 160c88c5224SJed Brown 161c88c5224SJed Brown PetscFunctionBegin; 162c88c5224SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1633ad4599aSBarry Smith if (mat) PetscValidPointer(mat,3); 164ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 165ce94432eSBarry Smith if (l <= 0 || mg->nlevels <= l) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Level %D must be in range {1,...,%D}",l,mg->nlevels-1); 166c88c5224SJed Brown if (!mglevels[l]->interpolate) { 1675aa31b60SBarry Smith if (!mglevels[l]->restrct) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must call PCMGSetInterpolation() or PCMGSetRestriction()"); 168c88c5224SJed Brown ierr = PCMGSetInterpolation(pc,l,mglevels[l]->restrct);CHKERRQ(ierr); 169c88c5224SJed Brown } 1703ad4599aSBarry Smith if (mat) *mat = mglevels[l]->interpolate; 171c88c5224SJed Brown PetscFunctionReturn(0); 172c88c5224SJed Brown } 173c88c5224SJed Brown 1744b9ad928SBarry Smith /*@ 175*eab52d2bSLawrence Mitchell PCMGSetRestriction - Sets the function to be used to restrict dual vectors 1764b9ad928SBarry Smith from level l to l-1. 1774b9ad928SBarry Smith 178ad4df100SBarry Smith Logically Collective on PC and Mat 1794b9ad928SBarry Smith 1804b9ad928SBarry Smith Input Parameters: 1814b9ad928SBarry Smith + pc - the multigrid context 182c88c5224SJed Brown . l - the level (0 is coarsest) to supply [Do not supply 0] 183c88c5224SJed Brown - mat - the restriction matrix 1844b9ad928SBarry Smith 1854b9ad928SBarry Smith Level: advanced 1864b9ad928SBarry Smith 1874b9ad928SBarry Smith Notes: 1884b9ad928SBarry Smith Usually this is the same matrix used also to set the interpolation 1894b9ad928SBarry Smith for the same level. 1904b9ad928SBarry Smith 1914b9ad928SBarry Smith One can pass in the interpolation matrix or its transpose; PETSc figures 1924b9ad928SBarry Smith out from the matrix size which one it is. 1934b9ad928SBarry Smith 194aea2a34eSBarry Smith If you do not set this, the transpose of the Mat set with PCMGSetInterpolation() 195fccaa45eSBarry Smith is used. 196fccaa45eSBarry Smith 1974b9ad928SBarry Smith .keywords: MG, set, multigrid, restriction, level 1984b9ad928SBarry Smith 199*eab52d2bSLawrence Mitchell .seealso: PCMGSetInterpolation(), PCMGetSetInjection() 2004b9ad928SBarry Smith @*/ 2017087cfbeSBarry Smith PetscErrorCode PCMGSetRestriction(PC pc,PetscInt l,Mat mat) 2024b9ad928SBarry Smith { 203fccaa45eSBarry Smith PetscErrorCode ierr; 204f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 205f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 2064b9ad928SBarry Smith 2074b9ad928SBarry Smith PetscFunctionBegin; 208c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 209c88c5224SJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 210ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 211ce94432eSBarry Smith if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Do not set restriction routine for coarsest level"); 212c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 2136bf464f9SBarry Smith ierr = MatDestroy(&mglevels[l]->restrct);CHKERRQ(ierr); 2142fa5cd67SKarl Rupp 215f3fbd535SBarry Smith mglevels[l]->restrct = mat; 2164b9ad928SBarry Smith PetscFunctionReturn(0); 2174b9ad928SBarry Smith } 2184b9ad928SBarry Smith 219c88c5224SJed Brown /*@ 220*eab52d2bSLawrence Mitchell PCMGGetRestriction - Gets the function to be used to restrict dual vectors 221c88c5224SJed Brown from level l to l-1. 222c88c5224SJed Brown 223c88c5224SJed Brown Logically Collective on PC and Mat 224c88c5224SJed Brown 225c88c5224SJed Brown Input Parameters: 226c88c5224SJed Brown + pc - the multigrid context 227c88c5224SJed Brown - l - the level (0 is coarsest) to supply [Do not supply 0] 228c88c5224SJed Brown 229c88c5224SJed Brown Output Parameter: 230c88c5224SJed Brown . mat - the restriction matrix 231c88c5224SJed Brown 232c88c5224SJed Brown Level: advanced 233c88c5224SJed Brown 234c88c5224SJed Brown .keywords: MG, get, multigrid, restriction, level 235c88c5224SJed Brown 236*eab52d2bSLawrence Mitchell .seealso: PCMGGetInterpolation(), PCMGSetRestriction(), PCMGGetRScale(), PCMGGetInjection() 237c88c5224SJed Brown @*/ 238c88c5224SJed Brown PetscErrorCode PCMGGetRestriction(PC pc,PetscInt l,Mat *mat) 239c88c5224SJed Brown { 240c88c5224SJed Brown PC_MG *mg = (PC_MG*)pc->data; 241c88c5224SJed Brown PC_MG_Levels **mglevels = mg->levels; 242c88c5224SJed Brown PetscErrorCode ierr; 243c88c5224SJed Brown 244c88c5224SJed Brown PetscFunctionBegin; 245c88c5224SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2463ad4599aSBarry Smith if (mat) PetscValidPointer(mat,3); 247ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 248ce94432eSBarry Smith if (l <= 0 || mg->nlevels <= l) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Level %D must be in range {1,...,%D}",l,mg->nlevels-1); 249c88c5224SJed Brown if (!mglevels[l]->restrct) { 250ce94432eSBarry Smith if (!mglevels[l]->interpolate) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must call PCMGSetRestriction() or PCMGSetInterpolation()"); 251c88c5224SJed Brown ierr = PCMGSetRestriction(pc,l,mglevels[l]->interpolate);CHKERRQ(ierr); 252c88c5224SJed Brown } 2533ad4599aSBarry Smith if (mat) *mat = mglevels[l]->restrct; 254c88c5224SJed Brown PetscFunctionReturn(0); 255c88c5224SJed Brown } 256c88c5224SJed Brown 25773250ac0SBarry Smith /*@ 25873250ac0SBarry Smith PCMGSetRScale - Sets the pointwise scaling for the restriction operator from level l to l-1. 25973250ac0SBarry Smith 260c88c5224SJed Brown Logically Collective on PC and Vec 261c88c5224SJed Brown 262c88c5224SJed Brown Input Parameters: 263c88c5224SJed Brown + pc - the multigrid context 264c88c5224SJed Brown - l - the level (0 is coarsest) to supply [Do not supply 0] 265c88c5224SJed Brown . rscale - the scaling 266c88c5224SJed Brown 267c88c5224SJed Brown Level: advanced 268c88c5224SJed Brown 269c88c5224SJed Brown Notes: 270*eab52d2bSLawrence Mitchell When evaluating a function on a coarse level one does not want to do F(R * x) one does F(rscale * R * x) where rscale is 1 over the row sums of R. It is preferable to use PCMGSetInjection() to control moving primal vectors. 271c88c5224SJed Brown 272c88c5224SJed Brown .keywords: MG, set, multigrid, restriction, level 273c88c5224SJed Brown 274*eab52d2bSLawrence Mitchell .seealso: PCMGSetInterpolation(), PCMGSetRestriction(), PCMGGetRScale(), PCMGSetInjection() 275c88c5224SJed Brown @*/ 276c88c5224SJed Brown PetscErrorCode PCMGSetRScale(PC pc,PetscInt l,Vec rscale) 277c88c5224SJed Brown { 278c88c5224SJed Brown PetscErrorCode ierr; 279c88c5224SJed Brown PC_MG *mg = (PC_MG*)pc->data; 280c88c5224SJed Brown PC_MG_Levels **mglevels = mg->levels; 281c88c5224SJed Brown 282c88c5224SJed Brown PetscFunctionBegin; 283c88c5224SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 284ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 285ce94432eSBarry Smith if (l <= 0 || mg->nlevels <= l) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Level %D must be in range {1,...,%D}",l,mg->nlevels-1); 286c88c5224SJed Brown ierr = PetscObjectReference((PetscObject)rscale);CHKERRQ(ierr); 287c88c5224SJed Brown ierr = VecDestroy(&mglevels[l]->rscale);CHKERRQ(ierr); 2882fa5cd67SKarl Rupp 289c88c5224SJed Brown mglevels[l]->rscale = rscale; 290c88c5224SJed Brown PetscFunctionReturn(0); 291c88c5224SJed Brown } 292c88c5224SJed Brown 293c88c5224SJed Brown /*@ 294c88c5224SJed Brown PCMGGetRScale - Gets the pointwise scaling for the restriction operator from level l to l-1. 295c88c5224SJed Brown 296c88c5224SJed Brown Collective on PC 29773250ac0SBarry Smith 29873250ac0SBarry Smith Input Parameters: 29973250ac0SBarry Smith + pc - the multigrid context 30073250ac0SBarry Smith . rscale - the scaling 30173250ac0SBarry Smith - l - the level (0 is coarsest) to supply [Do not supply 0] 30273250ac0SBarry Smith 30373250ac0SBarry Smith Level: advanced 30473250ac0SBarry Smith 30573250ac0SBarry Smith Notes: 306*eab52d2bSLawrence Mitchell When evaluating a function on a coarse level one does not want to do F(R * x) one does F(rscale * R * x) where rscale is 1 over the row sums of R. It is preferable to use PCMGGetInjection() to control moving primal vectors. 30773250ac0SBarry Smith 30873250ac0SBarry Smith .keywords: MG, set, multigrid, restriction, level 30973250ac0SBarry Smith 310*eab52d2bSLawrence Mitchell .seealso: PCMGSetInterpolation(), PCMGGetRestriction(), PCMGGetInjection() 31173250ac0SBarry Smith @*/ 312c88c5224SJed Brown PetscErrorCode PCMGGetRScale(PC pc,PetscInt l,Vec *rscale) 31373250ac0SBarry Smith { 31473250ac0SBarry Smith PetscErrorCode ierr; 31573250ac0SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 31673250ac0SBarry Smith PC_MG_Levels **mglevels = mg->levels; 31773250ac0SBarry Smith 31873250ac0SBarry Smith PetscFunctionBegin; 31973250ac0SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 320ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 321ce94432eSBarry Smith if (l <= 0 || mg->nlevels <= l) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Level %D must be in range {1,...,%D}",l,mg->nlevels-1); 322c88c5224SJed Brown if (!mglevels[l]->rscale) { 323c88c5224SJed Brown Mat R; 324c88c5224SJed Brown Vec X,Y,coarse,fine; 325c88c5224SJed Brown PetscInt M,N; 326c88c5224SJed Brown ierr = PCMGGetRestriction(pc,l,&R);CHKERRQ(ierr); 3272a7a6963SBarry Smith ierr = MatCreateVecs(R,&X,&Y);CHKERRQ(ierr); 328c88c5224SJed Brown ierr = MatGetSize(R,&M,&N);CHKERRQ(ierr); 3292fa5cd67SKarl Rupp if (M < N) { 3302fa5cd67SKarl Rupp fine = X; 3312fa5cd67SKarl Rupp coarse = Y; 3322fa5cd67SKarl Rupp } else if (N < M) { 3332fa5cd67SKarl Rupp fine = Y; coarse = X; 334ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)R),PETSC_ERR_SUP,"Restriction matrix is square, cannot determine which Vec is coarser"); 335c88c5224SJed Brown ierr = VecSet(fine,1.);CHKERRQ(ierr); 336c88c5224SJed Brown ierr = MatRestrict(R,fine,coarse);CHKERRQ(ierr); 337c88c5224SJed Brown ierr = VecDestroy(&fine);CHKERRQ(ierr); 338c88c5224SJed Brown ierr = VecReciprocal(coarse);CHKERRQ(ierr); 339c88c5224SJed Brown mglevels[l]->rscale = coarse; 340c88c5224SJed Brown } 341c88c5224SJed Brown *rscale = mglevels[l]->rscale; 34273250ac0SBarry Smith PetscFunctionReturn(0); 34373250ac0SBarry Smith } 34473250ac0SBarry Smith 345f39d8e23SSatish Balay /*@ 346*eab52d2bSLawrence Mitchell PCMGSetInjection - Sets the function to be used to inject primal vectors 347*eab52d2bSLawrence Mitchell from level l to l-1. 348*eab52d2bSLawrence Mitchell 349*eab52d2bSLawrence Mitchell Logically Collective on PC and Mat 350*eab52d2bSLawrence Mitchell 351*eab52d2bSLawrence Mitchell Input Parameters: 352*eab52d2bSLawrence Mitchell + pc - the multigrid context 353*eab52d2bSLawrence Mitchell . l - the level (0 is coarsest) to supply [Do not supply 0] 354*eab52d2bSLawrence Mitchell - mat - the injection matrix 355*eab52d2bSLawrence Mitchell 356*eab52d2bSLawrence Mitchell Level: advanced 357*eab52d2bSLawrence Mitchell 358*eab52d2bSLawrence Mitchell .keywords: MG, set, multigrid, restriction, injection, level 359*eab52d2bSLawrence Mitchell 360*eab52d2bSLawrence Mitchell .seealso: PCMGSetRestriction() 361*eab52d2bSLawrence Mitchell @*/ 362*eab52d2bSLawrence Mitchell PetscErrorCode PCMGSetInjection(PC pc,PetscInt l,Mat mat) 363*eab52d2bSLawrence Mitchell { 364*eab52d2bSLawrence Mitchell PetscErrorCode ierr; 365*eab52d2bSLawrence Mitchell PC_MG *mg = (PC_MG*)pc->data; 366*eab52d2bSLawrence Mitchell PC_MG_Levels **mglevels = mg->levels; 367*eab52d2bSLawrence Mitchell 368*eab52d2bSLawrence Mitchell PetscFunctionBegin; 369*eab52d2bSLawrence Mitchell PetscValidHeaderSpecific(pc,PC_CLASSID,1); 370*eab52d2bSLawrence Mitchell PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 371*eab52d2bSLawrence Mitchell if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 372*eab52d2bSLawrence Mitchell if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Do not set restriction routine for coarsest level"); 373*eab52d2bSLawrence Mitchell ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 374*eab52d2bSLawrence Mitchell ierr = MatDestroy(&mglevels[l]->inject);CHKERRQ(ierr); 375*eab52d2bSLawrence Mitchell 376*eab52d2bSLawrence Mitchell mglevels[l]->inject = mat; 377*eab52d2bSLawrence Mitchell PetscFunctionReturn(0); 378*eab52d2bSLawrence Mitchell } 379*eab52d2bSLawrence Mitchell 380*eab52d2bSLawrence Mitchell /*@ 381*eab52d2bSLawrence Mitchell PCMGGetInjection - Gets the function to be used to inject primal vectors 382*eab52d2bSLawrence Mitchell from level l to l-1. 383*eab52d2bSLawrence Mitchell 384*eab52d2bSLawrence Mitchell Logically Collective on PC and Mat 385*eab52d2bSLawrence Mitchell 386*eab52d2bSLawrence Mitchell Input Parameters: 387*eab52d2bSLawrence Mitchell + pc - the multigrid context 388*eab52d2bSLawrence Mitchell - l - the level (0 is coarsest) to supply [Do not supply 0] 389*eab52d2bSLawrence Mitchell 390*eab52d2bSLawrence Mitchell Output Parameter: 391*eab52d2bSLawrence Mitchell . mat - the restriction matrix 392*eab52d2bSLawrence Mitchell 393*eab52d2bSLawrence Mitchell Level: advanced 394*eab52d2bSLawrence Mitchell 395*eab52d2bSLawrence Mitchell .keywords: MG, get, multigrid, restriction, injection, level 396*eab52d2bSLawrence Mitchell 397*eab52d2bSLawrence Mitchell .seealso: PCMGSetInjection(), PCMGetGetRestriction() 398*eab52d2bSLawrence Mitchell @*/ 399*eab52d2bSLawrence Mitchell PetscErrorCode PCMGGetInjection(PC pc,PetscInt l,Mat *mat) 400*eab52d2bSLawrence Mitchell { 401*eab52d2bSLawrence Mitchell PC_MG *mg = (PC_MG*)pc->data; 402*eab52d2bSLawrence Mitchell PC_MG_Levels **mglevels = mg->levels; 403*eab52d2bSLawrence Mitchell 404*eab52d2bSLawrence Mitchell PetscFunctionBegin; 405*eab52d2bSLawrence Mitchell PetscValidHeaderSpecific(pc,PC_CLASSID,1); 406*eab52d2bSLawrence Mitchell if (mat) PetscValidPointer(mat,3); 407*eab52d2bSLawrence Mitchell if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 408*eab52d2bSLawrence Mitchell if (l <= 0 || mg->nlevels <= l) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Level %D must be in range {1,...,%D}",l,mg->nlevels-1); 409*eab52d2bSLawrence Mitchell if (!mglevels[l]->inject) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must call PCMGSetInjection() before calling"); 410*eab52d2bSLawrence Mitchell if (mat) *mat = mglevels[l]->inject; 411*eab52d2bSLawrence Mitchell PetscFunctionReturn(0); 412*eab52d2bSLawrence Mitchell } 413*eab52d2bSLawrence Mitchell 414*eab52d2bSLawrence Mitchell /*@ 41597177400SBarry Smith PCMGGetSmoother - Gets the KSP context to be used as smoother for 41697177400SBarry Smith both pre- and post-smoothing. Call both PCMGGetSmootherUp() and 41797177400SBarry Smith PCMGGetSmootherDown() to use different functions for pre- and 4184b9ad928SBarry Smith post-smoothing. 4194b9ad928SBarry Smith 4204b9ad928SBarry Smith Not Collective, KSP returned is parallel if PC is 4214b9ad928SBarry Smith 4224b9ad928SBarry Smith Input Parameters: 4234b9ad928SBarry Smith + pc - the multigrid context 4244b9ad928SBarry Smith - l - the level (0 is coarsest) to supply 4254b9ad928SBarry Smith 4264b9ad928SBarry Smith Ouput Parameters: 4274b9ad928SBarry Smith . ksp - the smoother 4284b9ad928SBarry Smith 42957420d5bSBarry Smith Notes: 43057420d5bSBarry Smith Once you have called this routine, you can call KSPSetOperators(ksp,...) on the resulting ksp to provide the operators for the smoother for this level. 43157420d5bSBarry Smith You can also modify smoother options by calling the various KSPSetXXX() options on this ksp. In addition you can call KSPGetPC(ksp,&pc) 43257420d5bSBarry Smith and modify PC options for the smoother; for example PCSetType(pc,PCSOR); to use SOR smoothing. 43357420d5bSBarry Smith 4344b9ad928SBarry Smith Level: advanced 4354b9ad928SBarry Smith 4364b9ad928SBarry Smith .keywords: MG, get, multigrid, level, smoother, pre-smoother, post-smoother 4374b9ad928SBarry Smith 43897177400SBarry Smith .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown() 4394b9ad928SBarry Smith @*/ 4407087cfbeSBarry Smith PetscErrorCode PCMGGetSmoother(PC pc,PetscInt l,KSP *ksp) 4414b9ad928SBarry Smith { 442f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 443f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 4444b9ad928SBarry Smith 4454b9ad928SBarry Smith PetscFunctionBegin; 446c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 447f3fbd535SBarry Smith *ksp = mglevels[l]->smoothd; 4484b9ad928SBarry Smith PetscFunctionReturn(0); 4494b9ad928SBarry Smith } 4504b9ad928SBarry Smith 451f39d8e23SSatish Balay /*@ 45297177400SBarry Smith PCMGGetSmootherUp - Gets the KSP context to be used as smoother after 4534b9ad928SBarry Smith coarse grid correction (post-smoother). 4544b9ad928SBarry Smith 4554b9ad928SBarry Smith Not Collective, KSP returned is parallel if PC is 4564b9ad928SBarry Smith 4574b9ad928SBarry Smith Input Parameters: 4584b9ad928SBarry Smith + pc - the multigrid context 4594b9ad928SBarry Smith - l - the level (0 is coarsest) to supply 4604b9ad928SBarry Smith 4614b9ad928SBarry Smith Ouput Parameters: 4624b9ad928SBarry Smith . ksp - the smoother 4634b9ad928SBarry Smith 4644b9ad928SBarry Smith Level: advanced 4654b9ad928SBarry Smith 46689cce641SBarry Smith Notes: calling this will result in a different pre and post smoother so you may need to 46789cce641SBarry Smith set options on the pre smoother also 46889cce641SBarry Smith 4694b9ad928SBarry Smith .keywords: MG, multigrid, get, smoother, up, post-smoother, level 4704b9ad928SBarry Smith 47197177400SBarry Smith .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown() 4724b9ad928SBarry Smith @*/ 4737087cfbeSBarry Smith PetscErrorCode PCMGGetSmootherUp(PC pc,PetscInt l,KSP *ksp) 4744b9ad928SBarry Smith { 475f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 476f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 477dfbe8321SBarry Smith PetscErrorCode ierr; 478f69a0ea3SMatthew Knepley const char *prefix; 4794b9ad928SBarry Smith MPI_Comm comm; 4804b9ad928SBarry Smith 4814b9ad928SBarry Smith PetscFunctionBegin; 482c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 4834b9ad928SBarry Smith /* 4844b9ad928SBarry Smith This is called only if user wants a different pre-smoother from post. 4854b9ad928SBarry Smith Thus we check if a different one has already been allocated, 4864b9ad928SBarry Smith if not we allocate it. 4874b9ad928SBarry Smith */ 488ce94432eSBarry Smith if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"There is no such thing as a up smoother on the coarse grid"); 489f3fbd535SBarry Smith if (mglevels[l]->smoothu == mglevels[l]->smoothd) { 49019fd82e9SBarry Smith KSPType ksptype; 49119fd82e9SBarry Smith PCType pctype; 492336babb1SJed Brown PC ipc; 493336babb1SJed Brown PetscReal rtol,abstol,dtol; 494336babb1SJed Brown PetscInt maxits; 495336babb1SJed Brown KSPNormType normtype; 496f3fbd535SBarry Smith ierr = PetscObjectGetComm((PetscObject)mglevels[l]->smoothd,&comm);CHKERRQ(ierr); 497f3fbd535SBarry Smith ierr = KSPGetOptionsPrefix(mglevels[l]->smoothd,&prefix);CHKERRQ(ierr); 498336babb1SJed Brown ierr = KSPGetTolerances(mglevels[l]->smoothd,&rtol,&abstol,&dtol,&maxits);CHKERRQ(ierr); 4993bf036e2SBarry Smith ierr = KSPGetType(mglevels[l]->smoothd,&ksptype);CHKERRQ(ierr); 500336babb1SJed Brown ierr = KSPGetNormType(mglevels[l]->smoothd,&normtype);CHKERRQ(ierr); 501336babb1SJed Brown ierr = KSPGetPC(mglevels[l]->smoothd,&ipc);CHKERRQ(ierr); 502336babb1SJed Brown ierr = PCGetType(ipc,&pctype);CHKERRQ(ierr); 503336babb1SJed Brown 504f3fbd535SBarry Smith ierr = KSPCreate(comm,&mglevels[l]->smoothu);CHKERRQ(ierr); 505422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(mglevels[l]->smoothu,pc->erroriffailure);CHKERRQ(ierr); 506f3fbd535SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)mglevels[l]->smoothu,(PetscObject)pc,mglevels[0]->levels-l);CHKERRQ(ierr); 507f3fbd535SBarry Smith ierr = KSPSetOptionsPrefix(mglevels[l]->smoothu,prefix);CHKERRQ(ierr); 508336babb1SJed Brown ierr = KSPSetTolerances(mglevels[l]->smoothu,rtol,abstol,dtol,maxits);CHKERRQ(ierr); 509336babb1SJed Brown ierr = KSPSetType(mglevels[l]->smoothu,ksptype);CHKERRQ(ierr); 510336babb1SJed Brown ierr = KSPSetNormType(mglevels[l]->smoothu,normtype);CHKERRQ(ierr); 5110059c7bdSJed Brown ierr = KSPSetConvergenceTest(mglevels[l]->smoothu,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr); 512336babb1SJed Brown ierr = KSPGetPC(mglevels[l]->smoothu,&ipc);CHKERRQ(ierr); 513336babb1SJed Brown ierr = PCSetType(ipc,pctype);CHKERRQ(ierr); 5143bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)mglevels[l]->smoothu);CHKERRQ(ierr); 515ab83eea4SMatthew G. Knepley ierr = PetscObjectComposedDataSetInt((PetscObject) mglevels[l]->smoothu, PetscMGLevelId, mglevels[l]->level);CHKERRQ(ierr); 5164b9ad928SBarry Smith } 517f3fbd535SBarry Smith if (ksp) *ksp = mglevels[l]->smoothu; 5184b9ad928SBarry Smith PetscFunctionReturn(0); 5194b9ad928SBarry Smith } 5204b9ad928SBarry Smith 521f39d8e23SSatish Balay /*@ 52297177400SBarry Smith PCMGGetSmootherDown - Gets the KSP context to be used as smoother before 5234b9ad928SBarry Smith coarse grid correction (pre-smoother). 5244b9ad928SBarry Smith 5254b9ad928SBarry Smith Not Collective, KSP returned is parallel if PC is 5264b9ad928SBarry Smith 5274b9ad928SBarry Smith Input Parameters: 5284b9ad928SBarry Smith + pc - the multigrid context 5294b9ad928SBarry Smith - l - the level (0 is coarsest) to supply 5304b9ad928SBarry Smith 5314b9ad928SBarry Smith Ouput Parameters: 5324b9ad928SBarry Smith . ksp - the smoother 5334b9ad928SBarry Smith 5344b9ad928SBarry Smith Level: advanced 5354b9ad928SBarry Smith 53689cce641SBarry Smith Notes: calling this will result in a different pre and post smoother so you may need to 53789cce641SBarry Smith set options on the post smoother also 53889cce641SBarry Smith 5394b9ad928SBarry Smith .keywords: MG, multigrid, get, smoother, down, pre-smoother, level 5404b9ad928SBarry Smith 54197177400SBarry Smith .seealso: PCMGGetSmootherUp(), PCMGGetSmoother() 5424b9ad928SBarry Smith @*/ 5437087cfbeSBarry Smith PetscErrorCode PCMGGetSmootherDown(PC pc,PetscInt l,KSP *ksp) 5444b9ad928SBarry Smith { 545dfbe8321SBarry Smith PetscErrorCode ierr; 546f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 547f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 5484b9ad928SBarry Smith 5494b9ad928SBarry Smith PetscFunctionBegin; 550c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5514b9ad928SBarry Smith /* make sure smoother up and down are different */ 552c5eb9154SBarry Smith if (l) { 5530298fd71SBarry Smith ierr = PCMGGetSmootherUp(pc,l,NULL);CHKERRQ(ierr); 554d8148a5aSMatthew Knepley } 555f3fbd535SBarry Smith *ksp = mglevels[l]->smoothd; 5564b9ad928SBarry Smith PetscFunctionReturn(0); 5574b9ad928SBarry Smith } 5584b9ad928SBarry Smith 5594b9ad928SBarry Smith /*@ 560cab31ae5SJed Brown PCMGSetCycleTypeOnLevel - Sets the type of cycle (aka cycle index) to run on the specified level. 5614b9ad928SBarry Smith 562ad4df100SBarry Smith Logically Collective on PC 5634b9ad928SBarry Smith 5644b9ad928SBarry Smith Input Parameters: 5654b9ad928SBarry Smith + pc - the multigrid context 566c1cbb1deSBarry Smith . l - the level (0 is coarsest) 567c1cbb1deSBarry Smith - c - either PC_MG_CYCLE_V or PC_MG_CYCLE_W 5684b9ad928SBarry Smith 5694b9ad928SBarry Smith Level: advanced 5704b9ad928SBarry Smith 5714b9ad928SBarry Smith .keywords: MG, multigrid, set, cycles, V-cycle, W-cycle, level 5724b9ad928SBarry Smith 573c1cbb1deSBarry Smith .seealso: PCMGSetCycleType() 5744b9ad928SBarry Smith @*/ 575c1cbb1deSBarry Smith PetscErrorCode PCMGSetCycleTypeOnLevel(PC pc,PetscInt l,PCMGCycleType c) 5764b9ad928SBarry Smith { 577f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 578f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 5794b9ad928SBarry Smith 5804b9ad928SBarry Smith PetscFunctionBegin; 581c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 582ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 583c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(pc,l,2); 584c51679f6SSatish Balay PetscValidLogicalCollectiveEnum(pc,c,3); 585f3fbd535SBarry Smith mglevels[l]->cycles = c; 5864b9ad928SBarry Smith PetscFunctionReturn(0); 5874b9ad928SBarry Smith } 5884b9ad928SBarry Smith 5894b9ad928SBarry Smith /*@ 59097177400SBarry Smith PCMGSetRhs - Sets the vector space to be used to store the right-hand side 591fccaa45eSBarry Smith on a particular level. 5924b9ad928SBarry Smith 593ad4df100SBarry Smith Logically Collective on PC and Vec 5944b9ad928SBarry Smith 5954b9ad928SBarry Smith Input Parameters: 5964b9ad928SBarry Smith + pc - the multigrid context 5974b9ad928SBarry Smith . l - the level (0 is coarsest) this is to be used for 5984b9ad928SBarry Smith - c - the space 5994b9ad928SBarry Smith 6004b9ad928SBarry Smith Level: advanced 6014b9ad928SBarry Smith 602fccaa45eSBarry Smith Notes: If this is not provided PETSc will automatically generate one. 603fccaa45eSBarry Smith 604fccaa45eSBarry Smith You do not need to keep a reference to this vector if you do 605fccaa45eSBarry Smith not need it PCDestroy() will properly free it. 606fccaa45eSBarry Smith 6074b9ad928SBarry Smith .keywords: MG, multigrid, set, right-hand-side, rhs, level 6084b9ad928SBarry Smith 60997177400SBarry Smith .seealso: PCMGSetX(), PCMGSetR() 6104b9ad928SBarry Smith @*/ 6117087cfbeSBarry Smith PetscErrorCode PCMGSetRhs(PC pc,PetscInt l,Vec c) 6124b9ad928SBarry Smith { 613fccaa45eSBarry Smith PetscErrorCode ierr; 614f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 615f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 6164b9ad928SBarry Smith 6174b9ad928SBarry Smith PetscFunctionBegin; 618c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 619ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 620ce94432eSBarry Smith if (l == mglevels[0]->levels-1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Do not set rhs for finest level"); 621c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 6226bf464f9SBarry Smith ierr = VecDestroy(&mglevels[l]->b);CHKERRQ(ierr); 6232fa5cd67SKarl Rupp 624f3fbd535SBarry Smith mglevels[l]->b = c; 6254b9ad928SBarry Smith PetscFunctionReturn(0); 6264b9ad928SBarry Smith } 6274b9ad928SBarry Smith 6284b9ad928SBarry Smith /*@ 62997177400SBarry Smith PCMGSetX - Sets the vector space to be used to store the solution on a 630fccaa45eSBarry Smith particular level. 6314b9ad928SBarry Smith 632ad4df100SBarry Smith Logically Collective on PC and Vec 6334b9ad928SBarry Smith 6344b9ad928SBarry Smith Input Parameters: 6354b9ad928SBarry Smith + pc - the multigrid context 636251f4c67SDmitry Karpeev . l - the level (0 is coarsest) this is to be used for (do not supply the finest level) 6374b9ad928SBarry Smith - c - the space 6384b9ad928SBarry Smith 6394b9ad928SBarry Smith Level: advanced 6404b9ad928SBarry Smith 641fccaa45eSBarry Smith Notes: If this is not provided PETSc will automatically generate one. 642fccaa45eSBarry Smith 643fccaa45eSBarry Smith You do not need to keep a reference to this vector if you do 644fccaa45eSBarry Smith not need it PCDestroy() will properly free it. 645fccaa45eSBarry Smith 6464b9ad928SBarry Smith .keywords: MG, multigrid, set, solution, level 6474b9ad928SBarry Smith 64897177400SBarry Smith .seealso: PCMGSetRhs(), PCMGSetR() 6494b9ad928SBarry Smith @*/ 6507087cfbeSBarry Smith PetscErrorCode PCMGSetX(PC pc,PetscInt l,Vec c) 6514b9ad928SBarry Smith { 652fccaa45eSBarry Smith PetscErrorCode ierr; 653f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 654f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 6554b9ad928SBarry Smith 6564b9ad928SBarry Smith PetscFunctionBegin; 657c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 658ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 659ce94432eSBarry Smith if (l == mglevels[0]->levels-1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Do not set x for finest level"); 660c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 6616bf464f9SBarry Smith ierr = VecDestroy(&mglevels[l]->x);CHKERRQ(ierr); 6622fa5cd67SKarl Rupp 663f3fbd535SBarry Smith mglevels[l]->x = c; 6644b9ad928SBarry Smith PetscFunctionReturn(0); 6654b9ad928SBarry Smith } 6664b9ad928SBarry Smith 6674b9ad928SBarry Smith /*@ 66897177400SBarry Smith PCMGSetR - Sets the vector space to be used to store the residual on a 669fccaa45eSBarry Smith particular level. 6704b9ad928SBarry Smith 671ad4df100SBarry Smith Logically Collective on PC and Vec 6724b9ad928SBarry Smith 6734b9ad928SBarry Smith Input Parameters: 6744b9ad928SBarry Smith + pc - the multigrid context 6754b9ad928SBarry Smith . l - the level (0 is coarsest) this is to be used for 6764b9ad928SBarry Smith - c - the space 6774b9ad928SBarry Smith 6784b9ad928SBarry Smith Level: advanced 6794b9ad928SBarry Smith 680fccaa45eSBarry Smith Notes: If this is not provided PETSc will automatically generate one. 681fccaa45eSBarry Smith 682fccaa45eSBarry Smith You do not need to keep a reference to this vector if you do 683fccaa45eSBarry Smith not need it PCDestroy() will properly free it. 684fccaa45eSBarry Smith 6854b9ad928SBarry Smith .keywords: MG, multigrid, set, residual, level 6864b9ad928SBarry Smith @*/ 6877087cfbeSBarry Smith PetscErrorCode PCMGSetR(PC pc,PetscInt l,Vec c) 6884b9ad928SBarry Smith { 689fccaa45eSBarry Smith PetscErrorCode ierr; 690f3fbd535SBarry Smith PC_MG *mg = (PC_MG*)pc->data; 691f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 6924b9ad928SBarry Smith 6934b9ad928SBarry Smith PetscFunctionBegin; 694c5eb9154SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 695ce94432eSBarry Smith if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 696ce94432eSBarry Smith if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Need not set residual vector for coarse grid"); 697c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 6986bf464f9SBarry Smith ierr = VecDestroy(&mglevels[l]->r);CHKERRQ(ierr); 6992fa5cd67SKarl Rupp 700f3fbd535SBarry Smith mglevels[l]->r = c; 7014b9ad928SBarry Smith PetscFunctionReturn(0); 7024b9ad928SBarry Smith } 703