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 8d083f849SBarry Smith Collective on Mat 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 20db781477SPatrick Sanan .seealso: `PCMGSetResidual()` 214b9ad928SBarry Smith @*/ 229371c9d4SSatish Balay PetscErrorCode PCMGResidualDefault(Mat mat, Vec b, Vec x, Vec r) { 234b9ad928SBarry Smith PetscFunctionBegin; 249566063dSJacob Faibussowitsch PetscCall(MatResidual(mat, b, x, r)); 254b9ad928SBarry Smith PetscFunctionReturn(0); 264b9ad928SBarry Smith } 274b9ad928SBarry Smith 28fcb023d4SJed Brown /*@C 29fcb023d4SJed Brown PCMGResidualTransposeDefault - Default routine to calculate the residual of the transposed linear system 30fcb023d4SJed Brown 31fcb023d4SJed Brown Collective on Mat 32fcb023d4SJed Brown 33fcb023d4SJed Brown Input Parameters: 34fcb023d4SJed Brown + mat - the matrix 35fcb023d4SJed Brown . b - the right-hand-side 36fcb023d4SJed Brown - x - the approximate solution 37fcb023d4SJed Brown 38fcb023d4SJed Brown Output Parameter: 39fcb023d4SJed Brown . r - location to store the residual 40fcb023d4SJed Brown 41fcb023d4SJed Brown Level: developer 42fcb023d4SJed Brown 43db781477SPatrick Sanan .seealso: `PCMGSetResidualTranspose()` 44fcb023d4SJed Brown @*/ 459371c9d4SSatish Balay PetscErrorCode PCMGResidualTransposeDefault(Mat mat, Vec b, Vec x, Vec r) { 46fcb023d4SJed Brown PetscFunctionBegin; 479566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(mat, x, r)); 489566063dSJacob Faibussowitsch PetscCall(VecAYPX(r, -1.0, b)); 49fcb023d4SJed Brown PetscFunctionReturn(0); 50fcb023d4SJed Brown } 51fcb023d4SJed Brown 5230b0564aSStefano Zampini /*@C 5330b0564aSStefano Zampini PCMGMatResidualDefault - Default routine to calculate the residual. 5430b0564aSStefano Zampini 5530b0564aSStefano Zampini Collective on Mat 5630b0564aSStefano Zampini 5730b0564aSStefano Zampini Input Parameters: 5830b0564aSStefano Zampini + mat - the matrix 5930b0564aSStefano Zampini . b - the right-hand-side 6030b0564aSStefano Zampini - x - the approximate solution 6130b0564aSStefano Zampini 6230b0564aSStefano Zampini Output Parameter: 6330b0564aSStefano Zampini . r - location to store the residual 6430b0564aSStefano Zampini 6530b0564aSStefano Zampini Level: developer 6630b0564aSStefano Zampini 67db781477SPatrick Sanan .seealso: `PCMGSetMatResidual()` 6830b0564aSStefano Zampini @*/ 699371c9d4SSatish Balay PetscErrorCode PCMGMatResidualDefault(Mat mat, Mat b, Mat x, Mat r) { 7030b0564aSStefano Zampini PetscFunctionBegin; 719566063dSJacob Faibussowitsch PetscCall(MatMatMult(mat, x, MAT_REUSE_MATRIX, PETSC_DEFAULT, &r)); 729566063dSJacob Faibussowitsch PetscCall(MatAYPX(r, -1.0, b, UNKNOWN_NONZERO_PATTERN)); 7330b0564aSStefano Zampini PetscFunctionReturn(0); 7430b0564aSStefano Zampini } 7530b0564aSStefano Zampini 7630b0564aSStefano Zampini /*@C 7730b0564aSStefano Zampini PCMGMatResidualTransposeDefault - Default routine to calculate the residual of the transposed linear system 7830b0564aSStefano Zampini 7930b0564aSStefano Zampini Collective on Mat 8030b0564aSStefano Zampini 8130b0564aSStefano Zampini Input Parameters: 8230b0564aSStefano Zampini + mat - the matrix 8330b0564aSStefano Zampini . b - the right-hand-side 8430b0564aSStefano Zampini - x - the approximate solution 8530b0564aSStefano Zampini 8630b0564aSStefano Zampini Output Parameter: 8730b0564aSStefano Zampini . r - location to store the residual 8830b0564aSStefano Zampini 8930b0564aSStefano Zampini Level: developer 9030b0564aSStefano Zampini 91db781477SPatrick Sanan .seealso: `PCMGSetMatResidualTranspose()` 9230b0564aSStefano Zampini @*/ 939371c9d4SSatish Balay PetscErrorCode PCMGMatResidualTransposeDefault(Mat mat, Mat b, Mat x, Mat r) { 9430b0564aSStefano Zampini PetscFunctionBegin; 959566063dSJacob Faibussowitsch PetscCall(MatTransposeMatMult(mat, x, MAT_REUSE_MATRIX, PETSC_DEFAULT, &r)); 969566063dSJacob Faibussowitsch PetscCall(MatAYPX(r, -1.0, b, UNKNOWN_NONZERO_PATTERN)); 9730b0564aSStefano Zampini PetscFunctionReturn(0); 9830b0564aSStefano Zampini } 99f39d8e23SSatish Balay /*@ 10097177400SBarry Smith PCMGGetCoarseSolve - Gets the solver context to be used on the coarse grid. 1014b9ad928SBarry Smith 1024b9ad928SBarry Smith Not Collective 1034b9ad928SBarry Smith 1044b9ad928SBarry Smith Input Parameter: 1054b9ad928SBarry Smith . pc - the multigrid context 1064b9ad928SBarry Smith 1074b9ad928SBarry Smith Output Parameter: 1084b9ad928SBarry Smith . ksp - the coarse grid solver context 1094b9ad928SBarry Smith 1104b9ad928SBarry Smith Level: advanced 1114b9ad928SBarry Smith 112db781477SPatrick Sanan .seealso: `PCMGGetSmootherUp()`, `PCMGGetSmootherDown()`, `PCMGGetSmoother()` 1134b9ad928SBarry Smith @*/ 1149371c9d4SSatish Balay PetscErrorCode PCMGGetCoarseSolve(PC pc, KSP *ksp) { 115f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 116f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 1174b9ad928SBarry Smith 1184b9ad928SBarry Smith PetscFunctionBegin; 119c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 120f3fbd535SBarry Smith *ksp = mglevels[0]->smoothd; 1214b9ad928SBarry Smith PetscFunctionReturn(0); 1224b9ad928SBarry Smith } 1234b9ad928SBarry Smith 1244b9ad928SBarry Smith /*@C 12597177400SBarry Smith PCMGSetResidual - Sets the function to be used to calculate the residual 1264b9ad928SBarry Smith on the lth level. 1274b9ad928SBarry Smith 128d083f849SBarry Smith Logically Collective on PC 1294b9ad928SBarry Smith 1304b9ad928SBarry Smith Input Parameters: 1314b9ad928SBarry Smith + pc - the multigrid context 1324b9ad928SBarry Smith . l - the level (0 is coarsest) to supply 133157726a2SBarry Smith . residual - function used to form residual, if none is provided the previously provide one is used, if no 134d0e4de75SBarry Smith previous one were provided then a default is used 1354b9ad928SBarry Smith - mat - matrix associated with residual 1364b9ad928SBarry Smith 1374b9ad928SBarry Smith Level: advanced 1384b9ad928SBarry Smith 139db781477SPatrick Sanan .seealso: `PCMGResidualDefault()` 1404b9ad928SBarry Smith @*/ 1419371c9d4SSatish Balay PetscErrorCode PCMGSetResidual(PC pc, PetscInt l, PetscErrorCode (*residual)(Mat, Vec, Vec, Vec), Mat mat) { 142f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 143f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 1444b9ad928SBarry Smith 1454b9ad928SBarry Smith PetscFunctionBegin; 146c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 14728b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 1482fa5cd67SKarl Rupp if (residual) mglevels[l]->residual = residual; 14954b2cd4bSJed Brown if (!mglevels[l]->residual) mglevels[l]->residual = PCMGResidualDefault; 15030b0564aSStefano Zampini mglevels[l]->matresidual = PCMGMatResidualDefault; 1519566063dSJacob Faibussowitsch if (mat) PetscCall(PetscObjectReference((PetscObject)mat)); 1529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mglevels[l]->A)); 153f3fbd535SBarry Smith mglevels[l]->A = mat; 1544b9ad928SBarry Smith PetscFunctionReturn(0); 1554b9ad928SBarry Smith } 1564b9ad928SBarry Smith 157fcb023d4SJed Brown /*@C 158fcb023d4SJed Brown PCMGSetResidualTranspose - Sets the function to be used to calculate the residual of the transposed linear system 159fcb023d4SJed Brown on the lth level. 160fcb023d4SJed Brown 161fcb023d4SJed Brown Logically Collective on PC 162fcb023d4SJed Brown 163fcb023d4SJed Brown Input Parameters: 164fcb023d4SJed Brown + pc - the multigrid context 165fcb023d4SJed Brown . l - the level (0 is coarsest) to supply 166fcb023d4SJed Brown . residualt - function used to form transpose of residual, if none is provided the previously provide one is used, if no 167fcb023d4SJed Brown previous one were provided then a default is used 168fcb023d4SJed Brown - mat - matrix associated with residual 169fcb023d4SJed Brown 170fcb023d4SJed Brown Level: advanced 171fcb023d4SJed Brown 172db781477SPatrick Sanan .seealso: `PCMGResidualTransposeDefault()` 173fcb023d4SJed Brown @*/ 1749371c9d4SSatish Balay PetscErrorCode PCMGSetResidualTranspose(PC pc, PetscInt l, PetscErrorCode (*residualt)(Mat, Vec, Vec, Vec), Mat mat) { 175fcb023d4SJed Brown PC_MG *mg = (PC_MG *)pc->data; 176fcb023d4SJed Brown PC_MG_Levels **mglevels = mg->levels; 177fcb023d4SJed Brown 178fcb023d4SJed Brown PetscFunctionBegin; 179fcb023d4SJed Brown PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 18028b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 181fcb023d4SJed Brown if (residualt) mglevels[l]->residualtranspose = residualt; 182fcb023d4SJed Brown if (!mglevels[l]->residualtranspose) mglevels[l]->residualtranspose = PCMGResidualTransposeDefault; 18330b0564aSStefano Zampini mglevels[l]->matresidualtranspose = PCMGMatResidualTransposeDefault; 1849566063dSJacob Faibussowitsch if (mat) PetscCall(PetscObjectReference((PetscObject)mat)); 1859566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mglevels[l]->A)); 186fcb023d4SJed Brown mglevels[l]->A = mat; 187fcb023d4SJed Brown PetscFunctionReturn(0); 188fcb023d4SJed Brown } 189fcb023d4SJed Brown 1904b9ad928SBarry Smith /*@ 191aea2a34eSBarry Smith PCMGSetInterpolation - Sets the function to be used to calculate the 192bf5b2e24SBarry Smith interpolation from l-1 to the lth level 1934b9ad928SBarry Smith 194d083f849SBarry Smith Logically Collective on PC 1954b9ad928SBarry Smith 1964b9ad928SBarry Smith Input Parameters: 1974b9ad928SBarry Smith + pc - the multigrid context 1984b9ad928SBarry Smith . mat - the interpolation operator 199bf5b2e24SBarry Smith - l - the level (0 is coarsest) to supply [do not supply 0] 2004b9ad928SBarry Smith 2014b9ad928SBarry Smith Level: advanced 2024b9ad928SBarry Smith 2034b9ad928SBarry Smith Notes: 2044b9ad928SBarry Smith Usually this is the same matrix used also to set the restriction 2054b9ad928SBarry Smith for the same level. 2064b9ad928SBarry Smith 2074b9ad928SBarry Smith One can pass in the interpolation matrix or its transpose; PETSc figures 2084b9ad928SBarry Smith out from the matrix size which one it is. 2094b9ad928SBarry Smith 210db781477SPatrick Sanan .seealso: `PCMGSetRestriction()` 2114b9ad928SBarry Smith @*/ 2129371c9d4SSatish Balay PetscErrorCode PCMGSetInterpolation(PC pc, PetscInt l, Mat mat) { 213f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 214f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 2154b9ad928SBarry Smith 2164b9ad928SBarry Smith PetscFunctionBegin; 217c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 21828b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 21928b400f6SJacob Faibussowitsch PetscCheck(l, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Do not set interpolation routine for coarsest level"); 2209566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 2219566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mglevels[l]->interpolate)); 2222fa5cd67SKarl Rupp 223f3fbd535SBarry Smith mglevels[l]->interpolate = mat; 2244b9ad928SBarry Smith PetscFunctionReturn(0); 2254b9ad928SBarry Smith } 2264b9ad928SBarry Smith 2278a2c336bSFande Kong /*@ 22895750439SFande Kong PCMGSetOperators - Sets operator and preconditioning matrix for lth level 2298a2c336bSFande Kong 230d083f849SBarry Smith Logically Collective on PC 2318a2c336bSFande Kong 2328a2c336bSFande Kong Input Parameters: 2338a2c336bSFande Kong + pc - the multigrid context 2348a2c336bSFande Kong . Amat - the operator 2358a2c336bSFande Kong . pmat - the preconditioning operator 23695750439SFande Kong - l - the level (0 is the coarsest) to supply 2378a2c336bSFande Kong 2388a2c336bSFande Kong Level: advanced 2398a2c336bSFande Kong 2408a2c336bSFande Kong .keywords: multigrid, set, interpolate, level 2418a2c336bSFande Kong 242db781477SPatrick Sanan .seealso: `PCMGSetRestriction()`, `PCMGSetInterpolation()` 2438a2c336bSFande Kong @*/ 2449371c9d4SSatish Balay PetscErrorCode PCMGSetOperators(PC pc, PetscInt l, Mat Amat, Mat Pmat) { 245360ee056SFande Kong PC_MG *mg = (PC_MG *)pc->data; 246360ee056SFande Kong PC_MG_Levels **mglevels = mg->levels; 247360ee056SFande Kong 248360ee056SFande Kong PetscFunctionBegin; 249360ee056SFande Kong PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2508a2c336bSFande Kong PetscValidHeaderSpecific(Amat, MAT_CLASSID, 3); 2518a2c336bSFande Kong PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 4); 25228b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 2539566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(mglevels[l]->smoothd, Amat, Pmat)); 254360ee056SFande Kong PetscFunctionReturn(0); 255360ee056SFande Kong } 256360ee056SFande Kong 257c88c5224SJed Brown /*@ 258c88c5224SJed Brown PCMGGetInterpolation - Gets the function to be used to calculate the 259c88c5224SJed Brown interpolation from l-1 to the lth level 260c88c5224SJed Brown 261c88c5224SJed Brown Logically Collective on PC 262c88c5224SJed Brown 263c88c5224SJed Brown Input Parameters: 264c88c5224SJed Brown + pc - the multigrid context 265c88c5224SJed Brown - l - the level (0 is coarsest) to supply [Do not supply 0] 266c88c5224SJed Brown 267c88c5224SJed Brown Output Parameter: 2683ad4599aSBarry Smith . mat - the interpolation matrix, can be NULL 269c88c5224SJed Brown 270c88c5224SJed Brown Level: advanced 271c88c5224SJed Brown 272db781477SPatrick Sanan .seealso: `PCMGGetRestriction()`, `PCMGSetInterpolation()`, `PCMGGetRScale()` 273c88c5224SJed Brown @*/ 2749371c9d4SSatish Balay PetscErrorCode PCMGGetInterpolation(PC pc, PetscInt l, Mat *mat) { 275c88c5224SJed Brown PC_MG *mg = (PC_MG *)pc->data; 276c88c5224SJed Brown PC_MG_Levels **mglevels = mg->levels; 277c88c5224SJed Brown 278c88c5224SJed Brown PetscFunctionBegin; 279c88c5224SJed Brown PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2803ad4599aSBarry Smith if (mat) PetscValidPointer(mat, 3); 28128b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 2822472a847SBarry Smith PetscCheck(l > 0 && l < mg->nlevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Level %" PetscInt_FMT " must be in range {1,...,%" PetscInt_FMT "}", l, mg->nlevels - 1); 283*48a46eb9SPierre Jolivet if (!mglevels[l]->interpolate && mglevels[l]->restrct) PetscCall(PCMGSetInterpolation(pc, l, mglevels[l]->restrct)); 2843ad4599aSBarry Smith if (mat) *mat = mglevels[l]->interpolate; 285c88c5224SJed Brown PetscFunctionReturn(0); 286c88c5224SJed Brown } 287c88c5224SJed Brown 2888a2c336bSFande Kong /*@ 289eab52d2bSLawrence Mitchell PCMGSetRestriction - Sets the function to be used to restrict dual vectors 2904b9ad928SBarry Smith from level l to l-1. 2914b9ad928SBarry Smith 292d083f849SBarry Smith Logically Collective on PC 2934b9ad928SBarry Smith 2944b9ad928SBarry Smith Input Parameters: 2954b9ad928SBarry Smith + pc - the multigrid context 296c88c5224SJed Brown . l - the level (0 is coarsest) to supply [Do not supply 0] 297c88c5224SJed Brown - mat - the restriction matrix 2984b9ad928SBarry Smith 2994b9ad928SBarry Smith Level: advanced 3004b9ad928SBarry Smith 3014b9ad928SBarry Smith Notes: 3024b9ad928SBarry Smith Usually this is the same matrix used also to set the interpolation 3034b9ad928SBarry Smith for the same level. 3044b9ad928SBarry Smith 3054b9ad928SBarry Smith One can pass in the interpolation matrix or its transpose; PETSc figures 3064b9ad928SBarry Smith out from the matrix size which one it is. 3074b9ad928SBarry Smith 308aea2a34eSBarry Smith If you do not set this, the transpose of the Mat set with PCMGSetInterpolation() 309fccaa45eSBarry Smith is used. 310fccaa45eSBarry Smith 311db781477SPatrick Sanan .seealso: `PCMGSetInterpolation()` 3124b9ad928SBarry Smith @*/ 3139371c9d4SSatish Balay PetscErrorCode PCMGSetRestriction(PC pc, PetscInt l, Mat mat) { 314f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 315f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 3164b9ad928SBarry Smith 3174b9ad928SBarry Smith PetscFunctionBegin; 318c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 319c88c5224SJed Brown PetscValidHeaderSpecific(mat, MAT_CLASSID, 3); 32028b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 32128b400f6SJacob Faibussowitsch PetscCheck(l, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Do not set restriction routine for coarsest level"); 3229566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 3239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mglevels[l]->restrct)); 3242fa5cd67SKarl Rupp 325f3fbd535SBarry Smith mglevels[l]->restrct = mat; 3264b9ad928SBarry Smith PetscFunctionReturn(0); 3274b9ad928SBarry Smith } 3284b9ad928SBarry Smith 329c88c5224SJed Brown /*@ 330eab52d2bSLawrence Mitchell PCMGGetRestriction - Gets the function to be used to restrict dual vectors 331c88c5224SJed Brown from level l to l-1. 332c88c5224SJed Brown 333d083f849SBarry Smith Logically Collective on PC 334c88c5224SJed Brown 335c88c5224SJed Brown Input Parameters: 336c88c5224SJed Brown + pc - the multigrid context 337c88c5224SJed Brown - l - the level (0 is coarsest) to supply [Do not supply 0] 338c88c5224SJed Brown 339c88c5224SJed Brown Output Parameter: 340c88c5224SJed Brown . mat - the restriction matrix 341c88c5224SJed Brown 342c88c5224SJed Brown Level: advanced 343c88c5224SJed Brown 344db781477SPatrick Sanan .seealso: `PCMGGetInterpolation()`, `PCMGSetRestriction()`, `PCMGGetRScale()`, `PCMGGetInjection()` 345c88c5224SJed Brown @*/ 3469371c9d4SSatish Balay PetscErrorCode PCMGGetRestriction(PC pc, PetscInt l, Mat *mat) { 347c88c5224SJed Brown PC_MG *mg = (PC_MG *)pc->data; 348c88c5224SJed Brown PC_MG_Levels **mglevels = mg->levels; 349c88c5224SJed Brown 350c88c5224SJed Brown PetscFunctionBegin; 351c88c5224SJed Brown PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 3523ad4599aSBarry Smith if (mat) PetscValidPointer(mat, 3); 35328b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 3542472a847SBarry Smith PetscCheck(l > 0 && l < mg->nlevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Level %" PetscInt_FMT " must be in range {1,...,%" PetscInt_FMT "}", l, mg->nlevels - 1); 355*48a46eb9SPierre Jolivet if (!mglevels[l]->restrct && mglevels[l]->interpolate) PetscCall(PCMGSetRestriction(pc, l, mglevels[l]->interpolate)); 3563ad4599aSBarry Smith if (mat) *mat = mglevels[l]->restrct; 357c88c5224SJed Brown PetscFunctionReturn(0); 358c88c5224SJed Brown } 359c88c5224SJed Brown 36073250ac0SBarry Smith /*@ 36173250ac0SBarry Smith PCMGSetRScale - Sets the pointwise scaling for the restriction operator from level l to l-1. 36273250ac0SBarry Smith 363d083f849SBarry Smith Logically Collective on PC 364c88c5224SJed Brown 365c88c5224SJed Brown Input Parameters: 366c88c5224SJed Brown + pc - the multigrid context 367c88c5224SJed Brown - l - the level (0 is coarsest) to supply [Do not supply 0] 368c88c5224SJed Brown . rscale - the scaling 369c88c5224SJed Brown 370c88c5224SJed Brown Level: advanced 371c88c5224SJed Brown 372c88c5224SJed Brown Notes: 373eab52d2bSLawrence 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. 374c88c5224SJed Brown 375db781477SPatrick Sanan .seealso: `PCMGSetInterpolation()`, `PCMGSetRestriction()`, `PCMGGetRScale()`, `PCMGSetInjection()` 376c88c5224SJed Brown @*/ 3779371c9d4SSatish Balay PetscErrorCode PCMGSetRScale(PC pc, PetscInt l, Vec rscale) { 378c88c5224SJed Brown PC_MG *mg = (PC_MG *)pc->data; 379c88c5224SJed Brown PC_MG_Levels **mglevels = mg->levels; 380c88c5224SJed Brown 381c88c5224SJed Brown PetscFunctionBegin; 382c88c5224SJed Brown PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 38328b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 3842472a847SBarry Smith PetscCheck(l > 0 && l < mg->nlevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Level %" PetscInt_FMT " must be in range {1,...,%" PetscInt_FMT "}", l, mg->nlevels - 1); 3859566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)rscale)); 3869566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mglevels[l]->rscale)); 3872fa5cd67SKarl Rupp 388c88c5224SJed Brown mglevels[l]->rscale = rscale; 389c88c5224SJed Brown PetscFunctionReturn(0); 390c88c5224SJed Brown } 391c88c5224SJed Brown 392c88c5224SJed Brown /*@ 393c88c5224SJed Brown PCMGGetRScale - Gets the pointwise scaling for the restriction operator from level l to l-1. 394c88c5224SJed Brown 395c88c5224SJed Brown Collective on PC 39673250ac0SBarry Smith 39773250ac0SBarry Smith Input Parameters: 39873250ac0SBarry Smith + pc - the multigrid context 39973250ac0SBarry Smith . rscale - the scaling 40073250ac0SBarry Smith - l - the level (0 is coarsest) to supply [Do not supply 0] 40173250ac0SBarry Smith 40273250ac0SBarry Smith Level: advanced 40373250ac0SBarry Smith 40473250ac0SBarry Smith Notes: 405eab52d2bSLawrence 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. 40673250ac0SBarry Smith 407db781477SPatrick Sanan .seealso: `PCMGSetInterpolation()`, `PCMGGetRestriction()`, `PCMGGetInjection()` 40873250ac0SBarry Smith @*/ 4099371c9d4SSatish Balay PetscErrorCode PCMGGetRScale(PC pc, PetscInt l, Vec *rscale) { 41073250ac0SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 41173250ac0SBarry Smith PC_MG_Levels **mglevels = mg->levels; 41273250ac0SBarry Smith 41373250ac0SBarry Smith PetscFunctionBegin; 41473250ac0SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 41528b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 4162472a847SBarry Smith PetscCheck(l > 0 && l < mg->nlevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Level %" PetscInt_FMT " must be in range {1,...,%" PetscInt_FMT "}", l, mg->nlevels - 1); 417c88c5224SJed Brown if (!mglevels[l]->rscale) { 418c88c5224SJed Brown Mat R; 419c88c5224SJed Brown Vec X, Y, coarse, fine; 420c88c5224SJed Brown PetscInt M, N; 4219566063dSJacob Faibussowitsch PetscCall(PCMGGetRestriction(pc, l, &R)); 4229566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(R, &X, &Y)); 4239566063dSJacob Faibussowitsch PetscCall(MatGetSize(R, &M, &N)); 4242fa5cd67SKarl Rupp if (M < N) { 4252fa5cd67SKarl Rupp fine = X; 4262fa5cd67SKarl Rupp coarse = Y; 4272fa5cd67SKarl Rupp } else if (N < M) { 4289371c9d4SSatish Balay fine = Y; 4299371c9d4SSatish Balay coarse = X; 430ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)R), PETSC_ERR_SUP, "Restriction matrix is square, cannot determine which Vec is coarser"); 4319566063dSJacob Faibussowitsch PetscCall(VecSet(fine, 1.)); 4329566063dSJacob Faibussowitsch PetscCall(MatRestrict(R, fine, coarse)); 4339566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fine)); 4349566063dSJacob Faibussowitsch PetscCall(VecReciprocal(coarse)); 435c88c5224SJed Brown mglevels[l]->rscale = coarse; 436c88c5224SJed Brown } 437c88c5224SJed Brown *rscale = mglevels[l]->rscale; 43873250ac0SBarry Smith PetscFunctionReturn(0); 43973250ac0SBarry Smith } 44073250ac0SBarry Smith 441f39d8e23SSatish Balay /*@ 442eab52d2bSLawrence Mitchell PCMGSetInjection - Sets the function to be used to inject primal vectors 443eab52d2bSLawrence Mitchell from level l to l-1. 444eab52d2bSLawrence Mitchell 445d083f849SBarry Smith Logically Collective on PC 446eab52d2bSLawrence Mitchell 447eab52d2bSLawrence Mitchell Input Parameters: 448eab52d2bSLawrence Mitchell + pc - the multigrid context 449eab52d2bSLawrence Mitchell . l - the level (0 is coarsest) to supply [Do not supply 0] 450eab52d2bSLawrence Mitchell - mat - the injection matrix 451eab52d2bSLawrence Mitchell 452eab52d2bSLawrence Mitchell Level: advanced 453eab52d2bSLawrence Mitchell 454db781477SPatrick Sanan .seealso: `PCMGSetRestriction()` 455eab52d2bSLawrence Mitchell @*/ 4569371c9d4SSatish Balay PetscErrorCode PCMGSetInjection(PC pc, PetscInt l, Mat mat) { 457eab52d2bSLawrence Mitchell PC_MG *mg = (PC_MG *)pc->data; 458eab52d2bSLawrence Mitchell PC_MG_Levels **mglevels = mg->levels; 459eab52d2bSLawrence Mitchell 460eab52d2bSLawrence Mitchell PetscFunctionBegin; 461eab52d2bSLawrence Mitchell PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 462eab52d2bSLawrence Mitchell PetscValidHeaderSpecific(mat, MAT_CLASSID, 3); 46328b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 46428b400f6SJacob Faibussowitsch PetscCheck(l, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Do not set restriction routine for coarsest level"); 4659566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 4669566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mglevels[l]->inject)); 467eab52d2bSLawrence Mitchell 468eab52d2bSLawrence Mitchell mglevels[l]->inject = mat; 469eab52d2bSLawrence Mitchell PetscFunctionReturn(0); 470eab52d2bSLawrence Mitchell } 471eab52d2bSLawrence Mitchell 472eab52d2bSLawrence Mitchell /*@ 473eab52d2bSLawrence Mitchell PCMGGetInjection - Gets the function to be used to inject primal vectors 474eab52d2bSLawrence Mitchell from level l to l-1. 475eab52d2bSLawrence Mitchell 476d083f849SBarry Smith Logically Collective on PC 477eab52d2bSLawrence Mitchell 478eab52d2bSLawrence Mitchell Input Parameters: 479eab52d2bSLawrence Mitchell + pc - the multigrid context 480eab52d2bSLawrence Mitchell - l - the level (0 is coarsest) to supply [Do not supply 0] 481eab52d2bSLawrence Mitchell 482eab52d2bSLawrence Mitchell Output Parameter: 48399a38656SLawrence Mitchell . mat - the restriction matrix (may be NULL if no injection is available). 484eab52d2bSLawrence Mitchell 485eab52d2bSLawrence Mitchell Level: advanced 486eab52d2bSLawrence Mitchell 487db781477SPatrick Sanan .seealso: `PCMGSetInjection()`, `PCMGetGetRestriction()` 488eab52d2bSLawrence Mitchell @*/ 4899371c9d4SSatish Balay PetscErrorCode PCMGGetInjection(PC pc, PetscInt l, Mat *mat) { 490eab52d2bSLawrence Mitchell PC_MG *mg = (PC_MG *)pc->data; 491eab52d2bSLawrence Mitchell PC_MG_Levels **mglevels = mg->levels; 492eab52d2bSLawrence Mitchell 493eab52d2bSLawrence Mitchell PetscFunctionBegin; 494eab52d2bSLawrence Mitchell PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 495eab52d2bSLawrence Mitchell if (mat) PetscValidPointer(mat, 3); 49628b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 4972472a847SBarry Smith PetscCheck(l > 0 && l < mg->nlevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Level %" PetscInt_FMT " must be in range {1,...,%" PetscInt_FMT "}", l, mg->nlevels - 1); 498eab52d2bSLawrence Mitchell if (mat) *mat = mglevels[l]->inject; 499eab52d2bSLawrence Mitchell PetscFunctionReturn(0); 500eab52d2bSLawrence Mitchell } 501eab52d2bSLawrence Mitchell 502eab52d2bSLawrence Mitchell /*@ 50397177400SBarry Smith PCMGGetSmoother - Gets the KSP context to be used as smoother for 50497177400SBarry Smith both pre- and post-smoothing. Call both PCMGGetSmootherUp() and 50597177400SBarry Smith PCMGGetSmootherDown() to use different functions for pre- and 5064b9ad928SBarry Smith post-smoothing. 5074b9ad928SBarry Smith 5084b9ad928SBarry Smith Not Collective, KSP returned is parallel if PC is 5094b9ad928SBarry Smith 5104b9ad928SBarry Smith Input Parameters: 5114b9ad928SBarry Smith + pc - the multigrid context 5124b9ad928SBarry Smith - l - the level (0 is coarsest) to supply 5134b9ad928SBarry Smith 51401d2d390SJose E. Roman Output Parameter: 5154b9ad928SBarry Smith . ksp - the smoother 5164b9ad928SBarry Smith 51757420d5bSBarry Smith Notes: 51857420d5bSBarry 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. 51957420d5bSBarry Smith You can also modify smoother options by calling the various KSPSetXXX() options on this ksp. In addition you can call KSPGetPC(ksp,&pc) 52057420d5bSBarry Smith and modify PC options for the smoother; for example PCSetType(pc,PCSOR); to use SOR smoothing. 52157420d5bSBarry Smith 5224b9ad928SBarry Smith Level: advanced 5234b9ad928SBarry Smith 524db781477SPatrick Sanan .seealso: `PCMGGetSmootherUp()`, `PCMGGetSmootherDown()`, `PCMGGetCoarseSolve()` 5254b9ad928SBarry Smith @*/ 5269371c9d4SSatish Balay PetscErrorCode PCMGGetSmoother(PC pc, PetscInt l, KSP *ksp) { 527f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 528f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 5294b9ad928SBarry Smith 5304b9ad928SBarry Smith PetscFunctionBegin; 531c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 532f3fbd535SBarry Smith *ksp = mglevels[l]->smoothd; 5334b9ad928SBarry Smith PetscFunctionReturn(0); 5344b9ad928SBarry Smith } 5354b9ad928SBarry Smith 536f39d8e23SSatish Balay /*@ 53797177400SBarry Smith PCMGGetSmootherUp - Gets the KSP context to be used as smoother after 5384b9ad928SBarry Smith coarse grid correction (post-smoother). 5394b9ad928SBarry Smith 5404b9ad928SBarry Smith Not Collective, KSP returned is parallel if PC is 5414b9ad928SBarry Smith 5424b9ad928SBarry Smith Input Parameters: 5434b9ad928SBarry Smith + pc - the multigrid context 5444b9ad928SBarry Smith - l - the level (0 is coarsest) to supply 5454b9ad928SBarry Smith 54601d2d390SJose E. Roman Output Parameter: 5474b9ad928SBarry Smith . ksp - the smoother 5484b9ad928SBarry Smith 5494b9ad928SBarry Smith Level: advanced 5504b9ad928SBarry Smith 55195452b02SPatrick Sanan Notes: 55295452b02SPatrick Sanan calling this will result in a different pre and post smoother so you may need to 55389cce641SBarry Smith set options on the pre smoother also 55489cce641SBarry Smith 555db781477SPatrick Sanan .seealso: `PCMGGetSmootherUp()`, `PCMGGetSmootherDown()` 5564b9ad928SBarry Smith @*/ 5579371c9d4SSatish Balay PetscErrorCode PCMGGetSmootherUp(PC pc, PetscInt l, KSP *ksp) { 558f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 559f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 560f69a0ea3SMatthew Knepley const char *prefix; 5614b9ad928SBarry Smith MPI_Comm comm; 5624b9ad928SBarry Smith 5634b9ad928SBarry Smith PetscFunctionBegin; 564c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 5654b9ad928SBarry Smith /* 5664b9ad928SBarry Smith This is called only if user wants a different pre-smoother from post. 5674b9ad928SBarry Smith Thus we check if a different one has already been allocated, 5684b9ad928SBarry Smith if not we allocate it. 5694b9ad928SBarry Smith */ 57028b400f6SJacob Faibussowitsch PetscCheck(l, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "There is no such thing as a up smoother on the coarse grid"); 571f3fbd535SBarry Smith if (mglevels[l]->smoothu == mglevels[l]->smoothd) { 57219fd82e9SBarry Smith KSPType ksptype; 57319fd82e9SBarry Smith PCType pctype; 574336babb1SJed Brown PC ipc; 575336babb1SJed Brown PetscReal rtol, abstol, dtol; 576336babb1SJed Brown PetscInt maxits; 577336babb1SJed Brown KSPNormType normtype; 5789566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)mglevels[l]->smoothd, &comm)); 5799566063dSJacob Faibussowitsch PetscCall(KSPGetOptionsPrefix(mglevels[l]->smoothd, &prefix)); 5809566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(mglevels[l]->smoothd, &rtol, &abstol, &dtol, &maxits)); 5819566063dSJacob Faibussowitsch PetscCall(KSPGetType(mglevels[l]->smoothd, &ksptype)); 5829566063dSJacob Faibussowitsch PetscCall(KSPGetNormType(mglevels[l]->smoothd, &normtype)); 5839566063dSJacob Faibussowitsch PetscCall(KSPGetPC(mglevels[l]->smoothd, &ipc)); 5849566063dSJacob Faibussowitsch PetscCall(PCGetType(ipc, &pctype)); 585336babb1SJed Brown 5869566063dSJacob Faibussowitsch PetscCall(KSPCreate(comm, &mglevels[l]->smoothu)); 5879566063dSJacob Faibussowitsch PetscCall(KSPSetErrorIfNotConverged(mglevels[l]->smoothu, pc->erroriffailure)); 5889566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)mglevels[l]->smoothu, (PetscObject)pc, mglevels[0]->levels - l)); 5899566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(mglevels[l]->smoothu, prefix)); 5909566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(mglevels[l]->smoothu, rtol, abstol, dtol, maxits)); 5919566063dSJacob Faibussowitsch PetscCall(KSPSetType(mglevels[l]->smoothu, ksptype)); 5929566063dSJacob Faibussowitsch PetscCall(KSPSetNormType(mglevels[l]->smoothu, normtype)); 5939566063dSJacob Faibussowitsch PetscCall(KSPSetConvergenceTest(mglevels[l]->smoothu, KSPConvergedSkip, NULL, NULL)); 5949566063dSJacob Faibussowitsch PetscCall(KSPGetPC(mglevels[l]->smoothu, &ipc)); 5959566063dSJacob Faibussowitsch PetscCall(PCSetType(ipc, pctype)); 5969566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)pc, (PetscObject)mglevels[l]->smoothu)); 5979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposedDataSetInt((PetscObject)mglevels[l]->smoothu, PetscMGLevelId, mglevels[l]->level)); 5984b9ad928SBarry Smith } 599f3fbd535SBarry Smith if (ksp) *ksp = mglevels[l]->smoothu; 6004b9ad928SBarry Smith PetscFunctionReturn(0); 6014b9ad928SBarry Smith } 6024b9ad928SBarry Smith 603f39d8e23SSatish Balay /*@ 60497177400SBarry Smith PCMGGetSmootherDown - Gets the KSP context to be used as smoother before 6054b9ad928SBarry Smith coarse grid correction (pre-smoother). 6064b9ad928SBarry Smith 6074b9ad928SBarry Smith Not Collective, KSP returned is parallel if PC is 6084b9ad928SBarry Smith 6094b9ad928SBarry Smith Input Parameters: 6104b9ad928SBarry Smith + pc - the multigrid context 6114b9ad928SBarry Smith - l - the level (0 is coarsest) to supply 6124b9ad928SBarry Smith 61301d2d390SJose E. Roman Output Parameter: 6144b9ad928SBarry Smith . ksp - the smoother 6154b9ad928SBarry Smith 6164b9ad928SBarry Smith Level: advanced 6174b9ad928SBarry Smith 61895452b02SPatrick Sanan Notes: 61995452b02SPatrick Sanan calling this will result in a different pre and post smoother so you may need to 62089cce641SBarry Smith set options on the post smoother also 62189cce641SBarry Smith 622db781477SPatrick Sanan .seealso: `PCMGGetSmootherUp()`, `PCMGGetSmoother()` 6234b9ad928SBarry Smith @*/ 6249371c9d4SSatish Balay PetscErrorCode PCMGGetSmootherDown(PC pc, PetscInt l, KSP *ksp) { 625f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 626f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 6274b9ad928SBarry Smith 6284b9ad928SBarry Smith PetscFunctionBegin; 629c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 6304b9ad928SBarry Smith /* make sure smoother up and down are different */ 6311baa6e33SBarry Smith if (l) PetscCall(PCMGGetSmootherUp(pc, l, NULL)); 632f3fbd535SBarry Smith *ksp = mglevels[l]->smoothd; 6334b9ad928SBarry Smith PetscFunctionReturn(0); 6344b9ad928SBarry Smith } 6354b9ad928SBarry Smith 6364b9ad928SBarry Smith /*@ 637cab31ae5SJed Brown PCMGSetCycleTypeOnLevel - Sets the type of cycle (aka cycle index) to run on the specified level. 6384b9ad928SBarry Smith 639ad4df100SBarry Smith Logically Collective on PC 6404b9ad928SBarry Smith 6414b9ad928SBarry Smith Input Parameters: 6424b9ad928SBarry Smith + pc - the multigrid context 643c1cbb1deSBarry Smith . l - the level (0 is coarsest) 644c1cbb1deSBarry Smith - c - either PC_MG_CYCLE_V or PC_MG_CYCLE_W 6454b9ad928SBarry Smith 6464b9ad928SBarry Smith Level: advanced 6474b9ad928SBarry Smith 648db781477SPatrick Sanan .seealso: `PCMGSetCycleType()` 6494b9ad928SBarry Smith @*/ 6509371c9d4SSatish Balay PetscErrorCode PCMGSetCycleTypeOnLevel(PC pc, PetscInt l, PCMGCycleType c) { 651f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 652f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 6534b9ad928SBarry Smith 6544b9ad928SBarry Smith PetscFunctionBegin; 655c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 65628b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 657c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(pc, l, 2); 658c51679f6SSatish Balay PetscValidLogicalCollectiveEnum(pc, c, 3); 659f3fbd535SBarry Smith mglevels[l]->cycles = c; 6604b9ad928SBarry Smith PetscFunctionReturn(0); 6614b9ad928SBarry Smith } 6624b9ad928SBarry Smith 6634b9ad928SBarry Smith /*@ 664f3b08a26SMatthew G. Knepley PCMGSetRhs - Sets the vector to be used to store the right-hand side on a particular level. 6654b9ad928SBarry Smith 666d083f849SBarry Smith Logically Collective on PC 6674b9ad928SBarry Smith 6684b9ad928SBarry Smith Input Parameters: 6694b9ad928SBarry Smith + pc - the multigrid context 6704b9ad928SBarry Smith . l - the level (0 is coarsest) this is to be used for 671f3b08a26SMatthew G. Knepley - c - the Vec 6724b9ad928SBarry Smith 6734b9ad928SBarry Smith Level: advanced 6744b9ad928SBarry Smith 67595452b02SPatrick Sanan Notes: 676f3b08a26SMatthew G. Knepley If this is not provided PETSc will automatically generate one. You do not need to keep a reference to this vector if you do not need it. PCDestroy() will properly free it. 677fccaa45eSBarry Smith 678f3b08a26SMatthew G. Knepley .keywords: MG, multigrid, set, right-hand-side, rhs, level 679db781477SPatrick Sanan .seealso: `PCMGSetX()`, `PCMGSetR()` 6804b9ad928SBarry Smith @*/ 6819371c9d4SSatish Balay PetscErrorCode PCMGSetRhs(PC pc, PetscInt l, Vec c) { 682f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 683f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 6844b9ad928SBarry Smith 6854b9ad928SBarry Smith PetscFunctionBegin; 686c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 68728b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 68808401ef6SPierre Jolivet PetscCheck(l != mglevels[0]->levels - 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Do not set rhs for finest level"); 6899566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)c)); 6909566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mglevels[l]->b)); 6912fa5cd67SKarl Rupp 692f3fbd535SBarry Smith mglevels[l]->b = c; 6934b9ad928SBarry Smith PetscFunctionReturn(0); 6944b9ad928SBarry Smith } 6954b9ad928SBarry Smith 6964b9ad928SBarry Smith /*@ 697f3b08a26SMatthew G. Knepley PCMGSetX - Sets the vector to be used to store the solution on a particular level. 6984b9ad928SBarry Smith 699d083f849SBarry Smith Logically Collective on PC 7004b9ad928SBarry Smith 7014b9ad928SBarry Smith Input Parameters: 7024b9ad928SBarry Smith + pc - the multigrid context 703251f4c67SDmitry Karpeev . l - the level (0 is coarsest) this is to be used for (do not supply the finest level) 704f3b08a26SMatthew G. Knepley - c - the Vec 7054b9ad928SBarry Smith 7064b9ad928SBarry Smith Level: advanced 7074b9ad928SBarry Smith 70895452b02SPatrick Sanan Notes: 709f3b08a26SMatthew G. Knepley If this is not provided PETSc will automatically generate one. You do not need to keep a reference to this vector if you do not need it. PCDestroy() will properly free it. 710fccaa45eSBarry Smith 711f3b08a26SMatthew G. Knepley .keywords: MG, multigrid, set, solution, level 712db781477SPatrick Sanan .seealso: `PCMGSetRhs()`, `PCMGSetR()` 7134b9ad928SBarry Smith @*/ 7149371c9d4SSatish Balay PetscErrorCode PCMGSetX(PC pc, PetscInt l, Vec c) { 715f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 716f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 7174b9ad928SBarry Smith 7184b9ad928SBarry Smith PetscFunctionBegin; 719c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 72028b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 72108401ef6SPierre Jolivet PetscCheck(l != mglevels[0]->levels - 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Do not set x for finest level"); 7229566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)c)); 7239566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mglevels[l]->x)); 7242fa5cd67SKarl Rupp 725f3fbd535SBarry Smith mglevels[l]->x = c; 7264b9ad928SBarry Smith PetscFunctionReturn(0); 7274b9ad928SBarry Smith } 7284b9ad928SBarry Smith 7294b9ad928SBarry Smith /*@ 730f3b08a26SMatthew G. Knepley PCMGSetR - Sets the vector to be used to store the residual on a particular level. 7314b9ad928SBarry Smith 732d083f849SBarry Smith Logically Collective on PC 7334b9ad928SBarry Smith 7344b9ad928SBarry Smith Input Parameters: 7354b9ad928SBarry Smith + pc - the multigrid context 7364b9ad928SBarry Smith . l - the level (0 is coarsest) this is to be used for 737f3b08a26SMatthew G. Knepley - c - the Vec 7384b9ad928SBarry Smith 7394b9ad928SBarry Smith Level: advanced 7404b9ad928SBarry Smith 74195452b02SPatrick Sanan Notes: 742f3b08a26SMatthew G. Knepley If this is not provided PETSc will automatically generate one. You do not need to keep a reference to this vector if you do not need it. PCDestroy() will properly free it. 743fccaa45eSBarry Smith 744f3b08a26SMatthew G. Knepley .keywords: MG, multigrid, set, residual, level 745db781477SPatrick Sanan .seealso: `PCMGSetRhs()`, `PCMGSetX()` 7464b9ad928SBarry Smith @*/ 7479371c9d4SSatish Balay PetscErrorCode PCMGSetR(PC pc, PetscInt l, Vec c) { 748f3fbd535SBarry Smith PC_MG *mg = (PC_MG *)pc->data; 749f3fbd535SBarry Smith PC_MG_Levels **mglevels = mg->levels; 7504b9ad928SBarry Smith 7514b9ad928SBarry Smith PetscFunctionBegin; 752c5eb9154SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 75328b400f6SJacob Faibussowitsch PetscCheck(mglevels, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set MG levels before calling"); 75428b400f6SJacob Faibussowitsch PetscCheck(l, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Need not set residual vector for coarse grid"); 7559566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)c)); 7569566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mglevels[l]->r)); 7572fa5cd67SKarl Rupp 758f3fbd535SBarry Smith mglevels[l]->r = c; 7594b9ad928SBarry Smith PetscFunctionReturn(0); 7604b9ad928SBarry Smith } 761