1 2 #include <petsc/private/pcmgimpl.h> /*I "petscksp.h" I*/ 3 4 /* ---------------------------------------------------------------------------*/ 5 /*@C 6 PCMGResidualDefault - Default routine to calculate the residual. 7 8 Collective on Mat and Vec 9 10 Input Parameters: 11 + mat - the matrix 12 . b - the right-hand-side 13 - x - the approximate solution 14 15 Output Parameter: 16 . r - location to store the residual 17 18 Level: developer 19 20 .keywords: MG, default, multigrid, residual 21 22 .seealso: PCMGSetResidual() 23 @*/ 24 PetscErrorCode PCMGResidualDefault(Mat mat,Vec b,Vec x,Vec r) 25 { 26 PetscErrorCode ierr; 27 28 PetscFunctionBegin; 29 ierr = MatResidual(mat,b,x,r);CHKERRQ(ierr); 30 PetscFunctionReturn(0); 31 } 32 33 /*@ 34 PCMGGetCoarseSolve - Gets the solver context to be used on the coarse grid. 35 36 Not Collective 37 38 Input Parameter: 39 . pc - the multigrid context 40 41 Output Parameter: 42 . ksp - the coarse grid solver context 43 44 Level: advanced 45 46 .keywords: MG, multigrid, get, coarse grid 47 @*/ 48 PetscErrorCode PCMGGetCoarseSolve(PC pc,KSP *ksp) 49 { 50 PC_MG *mg = (PC_MG*)pc->data; 51 PC_MG_Levels **mglevels = mg->levels; 52 53 PetscFunctionBegin; 54 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 55 *ksp = mglevels[0]->smoothd; 56 PetscFunctionReturn(0); 57 } 58 59 /*@C 60 PCMGSetResidual - Sets the function to be used to calculate the residual 61 on the lth level. 62 63 Logically Collective on PC and Mat 64 65 Input Parameters: 66 + pc - the multigrid context 67 . l - the level (0 is coarsest) to supply 68 . residual - function used to form residual, if none is provided the previously provide one is used, if no 69 previous one were provided then a default is used 70 - mat - matrix associated with residual 71 72 Level: advanced 73 74 .keywords: MG, set, multigrid, residual, level 75 76 .seealso: PCMGResidualDefault() 77 @*/ 78 PetscErrorCode PCMGSetResidual(PC pc,PetscInt l,PetscErrorCode (*residual)(Mat,Vec,Vec,Vec),Mat mat) 79 { 80 PC_MG *mg = (PC_MG*)pc->data; 81 PC_MG_Levels **mglevels = mg->levels; 82 PetscErrorCode ierr; 83 84 PetscFunctionBegin; 85 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 86 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 87 if (residual) mglevels[l]->residual = residual; 88 if (!mglevels[l]->residual) mglevels[l]->residual = PCMGResidualDefault; 89 if (mat) {ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);} 90 ierr = MatDestroy(&mglevels[l]->A);CHKERRQ(ierr); 91 mglevels[l]->A = mat; 92 PetscFunctionReturn(0); 93 } 94 95 /*@ 96 PCMGSetInterpolation - Sets the function to be used to calculate the 97 interpolation from l-1 to the lth level 98 99 Logically Collective on PC and Mat 100 101 Input Parameters: 102 + pc - the multigrid context 103 . mat - the interpolation operator 104 - l - the level (0 is coarsest) to supply [do not supply 0] 105 106 Level: advanced 107 108 Notes: 109 Usually this is the same matrix used also to set the restriction 110 for the same level. 111 112 One can pass in the interpolation matrix or its transpose; PETSc figures 113 out from the matrix size which one it is. 114 115 .keywords: multigrid, set, interpolate, level 116 117 .seealso: PCMGSetRestriction() 118 @*/ 119 PetscErrorCode PCMGSetInterpolation(PC pc,PetscInt l,Mat mat) 120 { 121 PC_MG *mg = (PC_MG*)pc->data; 122 PC_MG_Levels **mglevels = mg->levels; 123 PetscErrorCode ierr; 124 125 PetscFunctionBegin; 126 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 127 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 128 if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Do not set interpolation routine for coarsest level"); 129 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 130 ierr = MatDestroy(&mglevels[l]->interpolate);CHKERRQ(ierr); 131 132 mglevels[l]->interpolate = mat; 133 PetscFunctionReturn(0); 134 } 135 136 /*@ 137 PCMGGetInterpolation - Gets the function to be used to calculate the 138 interpolation from l-1 to the lth level 139 140 Logically Collective on PC 141 142 Input Parameters: 143 + pc - the multigrid context 144 - l - the level (0 is coarsest) to supply [Do not supply 0] 145 146 Output Parameter: 147 . mat - the interpolation matrix, can be NULL 148 149 Level: advanced 150 151 .keywords: MG, get, multigrid, interpolation, level 152 153 .seealso: PCMGGetRestriction(), PCMGSetInterpolation(), PCMGGetRScale() 154 @*/ 155 PetscErrorCode PCMGGetInterpolation(PC pc,PetscInt l,Mat *mat) 156 { 157 PC_MG *mg = (PC_MG*)pc->data; 158 PC_MG_Levels **mglevels = mg->levels; 159 PetscErrorCode ierr; 160 161 PetscFunctionBegin; 162 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 163 if (mat) PetscValidPointer(mat,3); 164 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 165 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); 166 if (!mglevels[l]->interpolate) { 167 if (!mglevels[l]->restrct) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must call PCMGSetInterpolation() or PCMGSetRestriction()"); 168 ierr = PCMGSetInterpolation(pc,l,mglevels[l]->restrct);CHKERRQ(ierr); 169 } 170 if (mat) *mat = mglevels[l]->interpolate; 171 PetscFunctionReturn(0); 172 } 173 174 /*@ 175 PCMGSetRestriction - Sets the function to be used to restrict dual vectors 176 from level l to l-1. 177 178 Logically Collective on PC and Mat 179 180 Input Parameters: 181 + pc - the multigrid context 182 . l - the level (0 is coarsest) to supply [Do not supply 0] 183 - mat - the restriction matrix 184 185 Level: advanced 186 187 Notes: 188 Usually this is the same matrix used also to set the interpolation 189 for the same level. 190 191 One can pass in the interpolation matrix or its transpose; PETSc figures 192 out from the matrix size which one it is. 193 194 If you do not set this, the transpose of the Mat set with PCMGSetInterpolation() 195 is used. 196 197 .keywords: MG, set, multigrid, restriction, level 198 199 .seealso: PCMGSetInterpolation(), PCMGetSetInjection() 200 @*/ 201 PetscErrorCode PCMGSetRestriction(PC pc,PetscInt l,Mat mat) 202 { 203 PetscErrorCode ierr; 204 PC_MG *mg = (PC_MG*)pc->data; 205 PC_MG_Levels **mglevels = mg->levels; 206 207 PetscFunctionBegin; 208 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 209 PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 210 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 211 if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Do not set restriction routine for coarsest level"); 212 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 213 ierr = MatDestroy(&mglevels[l]->restrct);CHKERRQ(ierr); 214 215 mglevels[l]->restrct = mat; 216 PetscFunctionReturn(0); 217 } 218 219 /*@ 220 PCMGGetRestriction - Gets the function to be used to restrict dual vectors 221 from level l to l-1. 222 223 Logically Collective on PC and Mat 224 225 Input Parameters: 226 + pc - the multigrid context 227 - l - the level (0 is coarsest) to supply [Do not supply 0] 228 229 Output Parameter: 230 . mat - the restriction matrix 231 232 Level: advanced 233 234 .keywords: MG, get, multigrid, restriction, level 235 236 .seealso: PCMGGetInterpolation(), PCMGSetRestriction(), PCMGGetRScale(), PCMGGetInjection() 237 @*/ 238 PetscErrorCode PCMGGetRestriction(PC pc,PetscInt l,Mat *mat) 239 { 240 PC_MG *mg = (PC_MG*)pc->data; 241 PC_MG_Levels **mglevels = mg->levels; 242 PetscErrorCode ierr; 243 244 PetscFunctionBegin; 245 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 246 if (mat) PetscValidPointer(mat,3); 247 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 248 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); 249 if (!mglevels[l]->restrct) { 250 if (!mglevels[l]->interpolate) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must call PCMGSetRestriction() or PCMGSetInterpolation()"); 251 ierr = PCMGSetRestriction(pc,l,mglevels[l]->interpolate);CHKERRQ(ierr); 252 } 253 if (mat) *mat = mglevels[l]->restrct; 254 PetscFunctionReturn(0); 255 } 256 257 /*@ 258 PCMGSetRScale - Sets the pointwise scaling for the restriction operator from level l to l-1. 259 260 Logically Collective on PC and Vec 261 262 Input Parameters: 263 + pc - the multigrid context 264 - l - the level (0 is coarsest) to supply [Do not supply 0] 265 . rscale - the scaling 266 267 Level: advanced 268 269 Notes: 270 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. 271 272 .keywords: MG, set, multigrid, restriction, level 273 274 .seealso: PCMGSetInterpolation(), PCMGSetRestriction(), PCMGGetRScale(), PCMGSetInjection() 275 @*/ 276 PetscErrorCode PCMGSetRScale(PC pc,PetscInt l,Vec rscale) 277 { 278 PetscErrorCode ierr; 279 PC_MG *mg = (PC_MG*)pc->data; 280 PC_MG_Levels **mglevels = mg->levels; 281 282 PetscFunctionBegin; 283 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 284 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 285 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); 286 ierr = PetscObjectReference((PetscObject)rscale);CHKERRQ(ierr); 287 ierr = VecDestroy(&mglevels[l]->rscale);CHKERRQ(ierr); 288 289 mglevels[l]->rscale = rscale; 290 PetscFunctionReturn(0); 291 } 292 293 /*@ 294 PCMGGetRScale - Gets the pointwise scaling for the restriction operator from level l to l-1. 295 296 Collective on PC 297 298 Input Parameters: 299 + pc - the multigrid context 300 . rscale - the scaling 301 - l - the level (0 is coarsest) to supply [Do not supply 0] 302 303 Level: advanced 304 305 Notes: 306 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. 307 308 .keywords: MG, set, multigrid, restriction, level 309 310 .seealso: PCMGSetInterpolation(), PCMGGetRestriction(), PCMGGetInjection() 311 @*/ 312 PetscErrorCode PCMGGetRScale(PC pc,PetscInt l,Vec *rscale) 313 { 314 PetscErrorCode ierr; 315 PC_MG *mg = (PC_MG*)pc->data; 316 PC_MG_Levels **mglevels = mg->levels; 317 318 PetscFunctionBegin; 319 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 320 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 321 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); 322 if (!mglevels[l]->rscale) { 323 Mat R; 324 Vec X,Y,coarse,fine; 325 PetscInt M,N; 326 ierr = PCMGGetRestriction(pc,l,&R);CHKERRQ(ierr); 327 ierr = MatCreateVecs(R,&X,&Y);CHKERRQ(ierr); 328 ierr = MatGetSize(R,&M,&N);CHKERRQ(ierr); 329 if (M < N) { 330 fine = X; 331 coarse = Y; 332 } else if (N < M) { 333 fine = Y; coarse = X; 334 } else SETERRQ(PetscObjectComm((PetscObject)R),PETSC_ERR_SUP,"Restriction matrix is square, cannot determine which Vec is coarser"); 335 ierr = VecSet(fine,1.);CHKERRQ(ierr); 336 ierr = MatRestrict(R,fine,coarse);CHKERRQ(ierr); 337 ierr = VecDestroy(&fine);CHKERRQ(ierr); 338 ierr = VecReciprocal(coarse);CHKERRQ(ierr); 339 mglevels[l]->rscale = coarse; 340 } 341 *rscale = mglevels[l]->rscale; 342 PetscFunctionReturn(0); 343 } 344 345 /*@ 346 PCMGSetInjection - Sets the function to be used to inject primal vectors 347 from level l to l-1. 348 349 Logically Collective on PC and Mat 350 351 Input Parameters: 352 + pc - the multigrid context 353 . l - the level (0 is coarsest) to supply [Do not supply 0] 354 - mat - the injection matrix 355 356 Level: advanced 357 358 .keywords: MG, set, multigrid, restriction, injection, level 359 360 .seealso: PCMGSetRestriction() 361 @*/ 362 PetscErrorCode PCMGSetInjection(PC pc,PetscInt l,Mat mat) 363 { 364 PetscErrorCode ierr; 365 PC_MG *mg = (PC_MG*)pc->data; 366 PC_MG_Levels **mglevels = mg->levels; 367 368 PetscFunctionBegin; 369 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 370 PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 371 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 372 if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Do not set restriction routine for coarsest level"); 373 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 374 ierr = MatDestroy(&mglevels[l]->inject);CHKERRQ(ierr); 375 376 mglevels[l]->inject = mat; 377 PetscFunctionReturn(0); 378 } 379 380 /*@ 381 PCMGGetInjection - Gets the function to be used to inject primal vectors 382 from level l to l-1. 383 384 Logically Collective on PC and Mat 385 386 Input Parameters: 387 + pc - the multigrid context 388 - l - the level (0 is coarsest) to supply [Do not supply 0] 389 390 Output Parameter: 391 . mat - the restriction matrix (may be NULL if no injection is available). 392 393 Level: advanced 394 395 .keywords: MG, get, multigrid, restriction, injection, level 396 397 .seealso: PCMGSetInjection(), PCMGetGetRestriction() 398 @*/ 399 PetscErrorCode PCMGGetInjection(PC pc,PetscInt l,Mat *mat) 400 { 401 PC_MG *mg = (PC_MG*)pc->data; 402 PC_MG_Levels **mglevels = mg->levels; 403 404 PetscFunctionBegin; 405 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 406 if (mat) PetscValidPointer(mat,3); 407 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 408 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 if (mat) *mat = mglevels[l]->inject; 410 PetscFunctionReturn(0); 411 } 412 413 /*@ 414 PCMGGetSmoother - Gets the KSP context to be used as smoother for 415 both pre- and post-smoothing. Call both PCMGGetSmootherUp() and 416 PCMGGetSmootherDown() to use different functions for pre- and 417 post-smoothing. 418 419 Not Collective, KSP returned is parallel if PC is 420 421 Input Parameters: 422 + pc - the multigrid context 423 - l - the level (0 is coarsest) to supply 424 425 Ouput Parameters: 426 . ksp - the smoother 427 428 Notes: 429 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. 430 You can also modify smoother options by calling the various KSPSetXXX() options on this ksp. In addition you can call KSPGetPC(ksp,&pc) 431 and modify PC options for the smoother; for example PCSetType(pc,PCSOR); to use SOR smoothing. 432 433 Level: advanced 434 435 .keywords: MG, get, multigrid, level, smoother, pre-smoother, post-smoother 436 437 .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown() 438 @*/ 439 PetscErrorCode PCMGGetSmoother(PC pc,PetscInt l,KSP *ksp) 440 { 441 PC_MG *mg = (PC_MG*)pc->data; 442 PC_MG_Levels **mglevels = mg->levels; 443 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 446 *ksp = mglevels[l]->smoothd; 447 PetscFunctionReturn(0); 448 } 449 450 /*@ 451 PCMGGetSmootherUp - Gets the KSP context to be used as smoother after 452 coarse grid correction (post-smoother). 453 454 Not Collective, KSP returned is parallel if PC is 455 456 Input Parameters: 457 + pc - the multigrid context 458 - l - the level (0 is coarsest) to supply 459 460 Ouput Parameters: 461 . ksp - the smoother 462 463 Level: advanced 464 465 Notes: 466 calling this will result in a different pre and post smoother so you may need to 467 set options on the pre smoother also 468 469 .keywords: MG, multigrid, get, smoother, up, post-smoother, level 470 471 .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown() 472 @*/ 473 PetscErrorCode PCMGGetSmootherUp(PC pc,PetscInt l,KSP *ksp) 474 { 475 PC_MG *mg = (PC_MG*)pc->data; 476 PC_MG_Levels **mglevels = mg->levels; 477 PetscErrorCode ierr; 478 const char *prefix; 479 MPI_Comm comm; 480 481 PetscFunctionBegin; 482 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 483 /* 484 This is called only if user wants a different pre-smoother from post. 485 Thus we check if a different one has already been allocated, 486 if not we allocate it. 487 */ 488 if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"There is no such thing as a up smoother on the coarse grid"); 489 if (mglevels[l]->smoothu == mglevels[l]->smoothd) { 490 KSPType ksptype; 491 PCType pctype; 492 PC ipc; 493 PetscReal rtol,abstol,dtol; 494 PetscInt maxits; 495 KSPNormType normtype; 496 ierr = PetscObjectGetComm((PetscObject)mglevels[l]->smoothd,&comm);CHKERRQ(ierr); 497 ierr = KSPGetOptionsPrefix(mglevels[l]->smoothd,&prefix);CHKERRQ(ierr); 498 ierr = KSPGetTolerances(mglevels[l]->smoothd,&rtol,&abstol,&dtol,&maxits);CHKERRQ(ierr); 499 ierr = KSPGetType(mglevels[l]->smoothd,&ksptype);CHKERRQ(ierr); 500 ierr = KSPGetNormType(mglevels[l]->smoothd,&normtype);CHKERRQ(ierr); 501 ierr = KSPGetPC(mglevels[l]->smoothd,&ipc);CHKERRQ(ierr); 502 ierr = PCGetType(ipc,&pctype);CHKERRQ(ierr); 503 504 ierr = KSPCreate(comm,&mglevels[l]->smoothu);CHKERRQ(ierr); 505 ierr = KSPSetErrorIfNotConverged(mglevels[l]->smoothu,pc->erroriffailure);CHKERRQ(ierr); 506 ierr = PetscObjectIncrementTabLevel((PetscObject)mglevels[l]->smoothu,(PetscObject)pc,mglevels[0]->levels-l);CHKERRQ(ierr); 507 ierr = KSPSetOptionsPrefix(mglevels[l]->smoothu,prefix);CHKERRQ(ierr); 508 ierr = KSPSetTolerances(mglevels[l]->smoothu,rtol,abstol,dtol,maxits);CHKERRQ(ierr); 509 ierr = KSPSetType(mglevels[l]->smoothu,ksptype);CHKERRQ(ierr); 510 ierr = KSPSetNormType(mglevels[l]->smoothu,normtype);CHKERRQ(ierr); 511 ierr = KSPSetConvergenceTest(mglevels[l]->smoothu,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr); 512 ierr = KSPGetPC(mglevels[l]->smoothu,&ipc);CHKERRQ(ierr); 513 ierr = PCSetType(ipc,pctype);CHKERRQ(ierr); 514 ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)mglevels[l]->smoothu);CHKERRQ(ierr); 515 ierr = PetscObjectComposedDataSetInt((PetscObject) mglevels[l]->smoothu, PetscMGLevelId, mglevels[l]->level);CHKERRQ(ierr); 516 } 517 if (ksp) *ksp = mglevels[l]->smoothu; 518 PetscFunctionReturn(0); 519 } 520 521 /*@ 522 PCMGGetSmootherDown - Gets the KSP context to be used as smoother before 523 coarse grid correction (pre-smoother). 524 525 Not Collective, KSP returned is parallel if PC is 526 527 Input Parameters: 528 + pc - the multigrid context 529 - l - the level (0 is coarsest) to supply 530 531 Ouput Parameters: 532 . ksp - the smoother 533 534 Level: advanced 535 536 Notes: 537 calling this will result in a different pre and post smoother so you may need to 538 set options on the post smoother also 539 540 .keywords: MG, multigrid, get, smoother, down, pre-smoother, level 541 542 .seealso: PCMGGetSmootherUp(), PCMGGetSmoother() 543 @*/ 544 PetscErrorCode PCMGGetSmootherDown(PC pc,PetscInt l,KSP *ksp) 545 { 546 PetscErrorCode ierr; 547 PC_MG *mg = (PC_MG*)pc->data; 548 PC_MG_Levels **mglevels = mg->levels; 549 550 PetscFunctionBegin; 551 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 552 /* make sure smoother up and down are different */ 553 if (l) { 554 ierr = PCMGGetSmootherUp(pc,l,NULL);CHKERRQ(ierr); 555 } 556 *ksp = mglevels[l]->smoothd; 557 PetscFunctionReturn(0); 558 } 559 560 /*@ 561 PCMGSetCycleTypeOnLevel - Sets the type of cycle (aka cycle index) to run on the specified level. 562 563 Logically Collective on PC 564 565 Input Parameters: 566 + pc - the multigrid context 567 . l - the level (0 is coarsest) 568 - c - either PC_MG_CYCLE_V or PC_MG_CYCLE_W 569 570 Level: advanced 571 572 .keywords: MG, multigrid, set, cycles, V-cycle, W-cycle, level 573 574 .seealso: PCMGSetCycleType() 575 @*/ 576 PetscErrorCode PCMGSetCycleTypeOnLevel(PC pc,PetscInt l,PCMGCycleType c) 577 { 578 PC_MG *mg = (PC_MG*)pc->data; 579 PC_MG_Levels **mglevels = mg->levels; 580 581 PetscFunctionBegin; 582 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 583 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 584 PetscValidLogicalCollectiveInt(pc,l,2); 585 PetscValidLogicalCollectiveEnum(pc,c,3); 586 mglevels[l]->cycles = c; 587 PetscFunctionReturn(0); 588 } 589 590 /*@ 591 PCMGSetRhs - Sets the vector space to be used to store the right-hand side 592 on a particular level. 593 594 Logically Collective on PC and Vec 595 596 Input Parameters: 597 + pc - the multigrid context 598 . l - the level (0 is coarsest) this is to be used for 599 - c - the space 600 601 Level: advanced 602 603 Notes: 604 If this is not provided PETSc will automatically generate one. 605 606 You do not need to keep a reference to this vector if you do 607 not need it PCDestroy() will properly free it. 608 609 .keywords: MG, multigrid, set, right-hand-side, rhs, level 610 611 .seealso: PCMGSetX(), PCMGSetR() 612 @*/ 613 PetscErrorCode PCMGSetRhs(PC pc,PetscInt l,Vec c) 614 { 615 PetscErrorCode ierr; 616 PC_MG *mg = (PC_MG*)pc->data; 617 PC_MG_Levels **mglevels = mg->levels; 618 619 PetscFunctionBegin; 620 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 621 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 622 if (l == mglevels[0]->levels-1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Do not set rhs for finest level"); 623 ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 624 ierr = VecDestroy(&mglevels[l]->b);CHKERRQ(ierr); 625 626 mglevels[l]->b = c; 627 PetscFunctionReturn(0); 628 } 629 630 /*@ 631 PCMGSetX - Sets the vector space to be used to store the solution on a 632 particular level. 633 634 Logically Collective on PC and Vec 635 636 Input Parameters: 637 + pc - the multigrid context 638 . l - the level (0 is coarsest) this is to be used for (do not supply the finest level) 639 - c - the space 640 641 Level: advanced 642 643 Notes: 644 If this is not provided PETSc will automatically generate one. 645 646 You do not need to keep a reference to this vector if you do 647 not need it PCDestroy() will properly free it. 648 649 .keywords: MG, multigrid, set, solution, level 650 651 .seealso: PCMGSetRhs(), PCMGSetR() 652 @*/ 653 PetscErrorCode PCMGSetX(PC pc,PetscInt l,Vec c) 654 { 655 PetscErrorCode ierr; 656 PC_MG *mg = (PC_MG*)pc->data; 657 PC_MG_Levels **mglevels = mg->levels; 658 659 PetscFunctionBegin; 660 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 661 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 662 if (l == mglevels[0]->levels-1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Do not set x for finest level"); 663 ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 664 ierr = VecDestroy(&mglevels[l]->x);CHKERRQ(ierr); 665 666 mglevels[l]->x = c; 667 PetscFunctionReturn(0); 668 } 669 670 /*@ 671 PCMGSetR - Sets the vector space to be used to store the residual on a 672 particular level. 673 674 Logically Collective on PC and Vec 675 676 Input Parameters: 677 + pc - the multigrid context 678 . l - the level (0 is coarsest) this is to be used for 679 - c - the space 680 681 Level: advanced 682 683 Notes: 684 If this is not provided PETSc will automatically generate one. 685 686 You do not need to keep a reference to this vector if you do 687 not need it PCDestroy() will properly free it. 688 689 .keywords: MG, multigrid, set, residual, level 690 @*/ 691 PetscErrorCode PCMGSetR(PC pc,PetscInt l,Vec c) 692 { 693 PetscErrorCode ierr; 694 PC_MG *mg = (PC_MG*)pc->data; 695 PC_MG_Levels **mglevels = mg->levels; 696 697 PetscFunctionBegin; 698 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 699 if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); 700 if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Need not set residual vector for coarse grid"); 701 ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 702 ierr = VecDestroy(&mglevels[l]->r);CHKERRQ(ierr); 703 704 mglevels[l]->r = c; 705 PetscFunctionReturn(0); 706 } 707