1 #include "../src/snes/impls/fas/fasimpls.h" /*I "petscsnesfas.h" I*/ 2 3 4 extern PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES, SNES *); 5 6 /* -------------- functions called on the fine level -------------- */ 7 8 #undef __FUNCT__ 9 #define __FUNCT__ "SNESFASSetType" 10 /*@ 11 SNESFASSetType - Sets the update and correction type used for FAS. 12 13 Logically Collective 14 15 Input Parameters: 16 + snes - FAS context 17 - fastype - SNES_FAS_ADDITIVE or SNES_FAS_MULTIPLICATIVE 18 19 Level: intermediate 20 21 .seealso: PCMGSetType() 22 @*/ 23 PetscErrorCode SNESFASSetType(SNES snes,SNESFASType fastype) 24 { 25 SNES_FAS *fas = (SNES_FAS*)snes->data; 26 PetscErrorCode ierr; 27 PetscFunctionBegin; 28 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29 PetscValidLogicalCollectiveEnum(snes,fastype,2); 30 fas->fastype = fastype; 31 if (fas->next) {ierr = SNESFASSetType(fas->next, fastype);CHKERRQ(ierr);} 32 PetscFunctionReturn(0); 33 } 34 35 36 #undef __FUNCT__ 37 #define __FUNCT__ "SNESFASGetType" 38 /*@ 39 SNESFASGetType - Sets the update and correction type used for FAS. 40 41 Logically Collective 42 43 Input Parameters: 44 . snes - FAS context 45 46 Output Parameters: 47 . fastype - SNES_FAS_ADDITIVE or SNES_FAS_MULTIPLICATIVE 48 49 Level: intermediate 50 51 .seealso: PCMGSetType() 52 @*/ 53 PetscErrorCode SNESFASGetType(SNES snes,SNESFASType *fastype) 54 { 55 SNES_FAS *fas = (SNES_FAS*)snes->data; 56 57 PetscFunctionBegin; 58 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 59 PetscValidPointer(fastype, 2); 60 *fastype = fas->fastype; 61 PetscFunctionReturn(0); 62 } 63 64 #undef __FUNCT__ 65 #define __FUNCT__ "SNESFASSetLevels" 66 /*@C 67 SNESFASSetLevels - Sets the number of levels to use with FAS. 68 Must be called before any other FAS routine. 69 70 Input Parameters: 71 + snes - the snes context 72 . levels - the number of levels 73 - comms - optional communicators for each level; this is to allow solving the coarser 74 problems on smaller sets of processors. Use PETSC_NULL_OBJECT for default in 75 Fortran. 76 77 Level: intermediate 78 79 Notes: 80 If the number of levels is one then the multigrid uses the -fas_levels prefix 81 for setting the level options rather than the -fas_coarse prefix. 82 83 .keywords: FAS, MG, set, levels, multigrid 84 85 .seealso: SNESFASGetLevels() 86 @*/ 87 PetscErrorCode SNESFASSetLevels(SNES snes, PetscInt levels, MPI_Comm * comms) { 88 PetscErrorCode ierr; 89 PetscInt i; 90 const char *optionsprefix; 91 char tprefix[128]; 92 SNES_FAS * fas = (SNES_FAS *)snes->data; 93 SNES prevsnes; 94 MPI_Comm comm; 95 PetscFunctionBegin; 96 comm = ((PetscObject)snes)->comm; 97 if (levels == fas->levels) { 98 if (!comms) 99 PetscFunctionReturn(0); 100 } 101 /* user has changed the number of levels; reset */ 102 ierr = SNESReset(snes);CHKERRQ(ierr); 103 /* destroy any coarser levels if necessary */ 104 if (fas->next) SNESDestroy(&fas->next);CHKERRQ(ierr); 105 fas->next = PETSC_NULL; 106 fas->previous = PETSC_NULL; 107 prevsnes = snes; 108 /* setup the finest level */ 109 ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 110 for (i = levels - 1; i >= 0; i--) { 111 if (comms) comm = comms[i]; 112 fas->level = i; 113 fas->levels = levels; 114 fas->fine = snes; 115 fas->next = PETSC_NULL; 116 if (i > 0) { 117 ierr = SNESCreate(comm, &fas->next);CHKERRQ(ierr); 118 sprintf(tprefix,"fas_levels_%d_cycle_",(int)fas->level); 119 ierr = SNESAppendOptionsPrefix(fas->next,tprefix);CHKERRQ(ierr); 120 ierr = SNESAppendOptionsPrefix(fas->next,optionsprefix);CHKERRQ(ierr); 121 ierr = SNESSetType(fas->next, SNESFAS);CHKERRQ(ierr); 122 ierr = SNESSetTolerances(fas->next, fas->next->abstol, fas->next->rtol, fas->next->stol, fas->n_cycles, fas->next->max_funcs);CHKERRQ(ierr); 123 ierr = PetscObjectIncrementTabLevel((PetscObject)fas->next, (PetscObject)snes, levels - i);CHKERRQ(ierr); 124 ((SNES_FAS *)fas->next->data)->previous = prevsnes; 125 prevsnes = fas->next; 126 fas = (SNES_FAS *)prevsnes->data; 127 } 128 } 129 PetscFunctionReturn(0); 130 } 131 132 133 #undef __FUNCT__ 134 #define __FUNCT__ "SNESFASGetLevels" 135 /*@ 136 SNESFASGetLevels - Gets the number of levels in a FAS, including fine and coarse grids 137 138 Input Parameter: 139 . snes - the nonlinear solver context 140 141 Output parameter: 142 . levels - the number of levels 143 144 Level: advanced 145 146 .keywords: MG, get, levels, multigrid 147 148 .seealso: SNESFASSetLevels(), PCMGGetLevels() 149 @*/ 150 PetscErrorCode SNESFASGetLevels(SNES snes, PetscInt * levels) { 151 SNES_FAS * fas = (SNES_FAS *)snes->data; 152 PetscFunctionBegin; 153 *levels = fas->levels; 154 PetscFunctionReturn(0); 155 } 156 157 158 #undef __FUNCT__ 159 #define __FUNCT__ "SNESFASGetCycleSNES" 160 /*@ 161 SNESFASGetCycleSNES - Gets the SNES corresponding to a particular 162 level of the FAS hierarchy. 163 164 Input Parameters: 165 + snes - the multigrid context 166 level - the level to get 167 - lsnes - whether to use the nonlinear smoother or not 168 169 Level: advanced 170 171 .keywords: FAS, MG, set, cycles, Gauss-Seidel, multigrid 172 173 .seealso: SNESFASSetLevels(), SNESFASGetLevels() 174 @*/ 175 PetscErrorCode SNESFASGetCycleSNES(SNES snes,PetscInt level,SNES *lsnes) { 176 SNES_FAS *fas = (SNES_FAS*)snes->data; 177 PetscInt i; 178 179 PetscFunctionBegin; 180 if (level > fas->levels-1) SETERRQ2(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Requested level %D from SNESFAS containing %D levels",level,fas->levels); 181 if (fas->level != fas->levels - 1) 182 SETERRQ2(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"SNESFASGetCycleSNES may only be called on the finest-level SNES.",level,fas->level); 183 184 *lsnes = snes; 185 for (i = fas->level; i > level; i--) { 186 *lsnes = fas->next; 187 fas = (SNES_FAS *)(*lsnes)->data; 188 } 189 if (fas->level != level) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESFAS level hierarchy corrupt"); 190 PetscFunctionReturn(0); 191 } 192 193 #undef __FUNCT__ 194 #define __FUNCT__ "SNESFASSetNumberSmoothUp" 195 /*@ 196 SNESFASSetNumberSmoothUp - Sets the number of post-smoothing steps to 197 use on all levels. 198 199 Logically Collective on SNES 200 201 Input Parameters: 202 + snes - the multigrid context 203 - n - the number of smoothing steps 204 205 Options Database Key: 206 . -snes_fas_smoothup <n> - Sets number of pre-smoothing steps 207 208 Level: advanced 209 210 .keywords: FAS, MG, smooth, down, pre-smoothing, steps, multigrid 211 212 .seealso: SNESFASSetNumberSmoothDown() 213 @*/ 214 PetscErrorCode SNESFASSetNumberSmoothUp(SNES snes, PetscInt n) { 215 SNES_FAS * fas = (SNES_FAS *)snes->data; 216 PetscErrorCode ierr = 0; 217 PetscFunctionBegin; 218 fas->max_up_it = n; 219 if (!fas->smoothu) { 220 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu); 221 } 222 ierr = SNESSetTolerances(fas->smoothu, fas->smoothu->abstol, fas->smoothu->rtol, fas->smoothu->stol, n, fas->smoothu->max_funcs);CHKERRQ(ierr); 223 if (fas->next) { 224 ierr = SNESFASSetNumberSmoothUp(fas->next, n);CHKERRQ(ierr); 225 } 226 PetscFunctionReturn(0); 227 } 228 229 #undef __FUNCT__ 230 #define __FUNCT__ "SNESFASSetNumberSmoothDown" 231 /*@ 232 SNESFASSetNumberSmoothDown - Sets the number of pre-smoothing steps to 233 use on all levels. 234 235 Logically Collective on SNES 236 237 Input Parameters: 238 + snes - the multigrid context 239 - n - the number of smoothing steps 240 241 Options Database Key: 242 . -snes_fas_smoothdown <n> - Sets number of pre-smoothing steps 243 244 Level: advanced 245 246 .keywords: FAS, MG, smooth, down, pre-smoothing, steps, multigrid 247 248 .seealso: SNESFASSetNumberSmoothUp() 249 @*/ 250 PetscErrorCode SNESFASSetNumberSmoothDown(SNES snes, PetscInt n) { 251 SNES_FAS * fas = (SNES_FAS *)snes->data; 252 PetscErrorCode ierr = 0; 253 PetscFunctionBegin; 254 if (!fas->smoothu) { 255 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu); 256 } 257 if (!fas->smoothd) { 258 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd); 259 } 260 ierr = SNESSetTolerances(fas->smoothd, fas->smoothd->abstol, fas->smoothd->rtol, fas->smoothd->stol, n, fas->smoothd->max_funcs);CHKERRQ(ierr); 261 fas->max_down_it = n; 262 if (fas->next) { 263 ierr = SNESFASSetNumberSmoothDown(fas->next, n);CHKERRQ(ierr); 264 } 265 PetscFunctionReturn(0); 266 } 267 268 269 #undef __FUNCT__ 270 #define __FUNCT__ "SNESFASSetCycles" 271 /*@ 272 SNESFASSetCycles - Sets the number of FAS multigrid cycles to use each time a grid is visited. Use SNESFASSetCyclesOnLevel() for more 273 complicated cycling. 274 275 Logically Collective on SNES 276 277 Input Parameters: 278 + snes - the multigrid context 279 - cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle 280 281 Options Database Key: 282 $ -snes_fas_cycles 1 or 2 283 284 Level: advanced 285 286 .keywords: MG, set, cycles, V-cycle, W-cycle, multigrid 287 288 .seealso: SNESFASSetCyclesOnLevel() 289 @*/ 290 PetscErrorCode SNESFASSetCycles(SNES snes, PetscInt cycles) { 291 SNES_FAS * fas = (SNES_FAS *)snes->data; 292 PetscErrorCode ierr; 293 PetscBool isFine; 294 PetscFunctionBegin; 295 ierr = SNESFASCycleIsFine(snes, &isFine); 296 fas->n_cycles = cycles; 297 if (!isFine) 298 ierr = SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);CHKERRQ(ierr); 299 if (fas->next) { 300 ierr = SNESFASSetCycles(fas->next, cycles);CHKERRQ(ierr); 301 } 302 PetscFunctionReturn(0); 303 } 304 305 306 #undef __FUNCT__ 307 #define __FUNCT__ "SNESFASSetMonitor" 308 /*@ 309 SNESFASSetMonitor - Sets the method-specific cycle monitoring 310 311 Logically Collective on SNES 312 313 Input Parameters: 314 + snes - the FAS context 315 - flg - monitor or not 316 317 Level: advanced 318 319 .keywords: FAS, monitor 320 321 .seealso: SNESFASSetCyclesOnLevel() 322 @*/ 323 PetscErrorCode SNESFASSetMonitor(SNES snes, PetscBool flg) { 324 SNES_FAS *fas = (SNES_FAS *)snes->data; 325 PetscErrorCode ierr; 326 PetscBool isFine; 327 PetscInt i, levels = fas->levels; 328 SNES levelsnes; 329 PetscFunctionBegin; 330 ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr); 331 if (isFine) { 332 for (i = 0; i < levels; i++) { 333 ierr = SNESFASGetCycleSNES(snes, i, &levelsnes); 334 fas = (SNES_FAS *)levelsnes->data; 335 if (flg) { 336 fas->monitor = PETSC_VIEWER_STDOUT_(((PetscObject)levelsnes)->comm);CHKERRQ(ierr); 337 /* set the monitors for the upsmoother and downsmoother */ 338 ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr); 339 ierr = SNESMonitorSet(levelsnes,SNESMonitorDefault,PETSC_NULL,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 340 } else { 341 /* unset the monitors on the coarse levels */ 342 if (i != fas->levels - 1) { 343 ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr); 344 } 345 } 346 } 347 } 348 PetscFunctionReturn(0); 349 } 350 351 #undef __FUNCT__ 352 #define __FUNCT__ "SNESFASCycleCreateSmoother_Private" 353 /* 354 Creates the default smoother type. 355 356 This is SNESNRICHARDSON on each fine level and SNESLS on the coarse level. 357 358 */ 359 PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES snes, SNES *smooth) { 360 SNES_FAS *fas; 361 const char *optionsprefix; 362 char tprefix[128]; 363 PetscErrorCode ierr; 364 SNES nsmooth; 365 PetscFunctionBegin; 366 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 367 fas = (SNES_FAS*)snes->data; 368 ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr); 369 /* create the default smoother */ 370 ierr = SNESCreate(((PetscObject)snes)->comm, &nsmooth);CHKERRQ(ierr); 371 if (fas->level == 0) { 372 sprintf(tprefix,"fas_coarse_"); 373 ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr); 374 ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr); 375 ierr = SNESSetType(nsmooth, SNESLS);CHKERRQ(ierr); 376 ierr = SNESSetTolerances(nsmooth, nsmooth->abstol, nsmooth->rtol, nsmooth->stol, nsmooth->max_its, nsmooth->max_funcs);CHKERRQ(ierr); 377 } else { 378 sprintf(tprefix,"fas_levels_%d_",(int)fas->level); 379 ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr); 380 ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr); 381 ierr = SNESSetType(nsmooth, SNESNRICHARDSON);CHKERRQ(ierr); 382 ierr = SNESSetTolerances(nsmooth, 0.0, 0.0, 0.0, fas->max_down_it, nsmooth->max_funcs);CHKERRQ(ierr); 383 } 384 ierr = PetscObjectIncrementTabLevel((PetscObject)nsmooth, (PetscObject)snes, 1);CHKERRQ(ierr); 385 *smooth = nsmooth; 386 PetscFunctionReturn(0); 387 } 388 389 /* ------------- Functions called on a particular level ----------------- */ 390 391 #undef __FUNCT__ 392 #define __FUNCT__ "SNESFASCycleSetCycles" 393 /*@ 394 SNESFASCycleSetCycles - Sets the number of cycles on a particular level. 395 396 Logically Collective on SNES 397 398 Input Parameters: 399 + snes - the multigrid context 400 . level - the level to set the number of cycles on 401 - cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle 402 403 Level: advanced 404 405 .keywords: SNES, FAS, set, cycles, V-cycle, W-cycle, multigrid 406 407 .seealso: SNESFASSetCycles() 408 @*/ 409 PetscErrorCode SNESFASCycleSetCycles(SNES snes, PetscInt cycles) { 410 SNES_FAS * fas = (SNES_FAS *)snes->data; 411 PetscErrorCode ierr; 412 PetscFunctionBegin; 413 fas->n_cycles = cycles; 414 ierr = SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);CHKERRQ(ierr); 415 PetscFunctionReturn(0); 416 } 417 418 419 #undef __FUNCT__ 420 #define __FUNCT__ "SNESFASCycleGetSmoother" 421 /*@ 422 SNESFASCycleGetSmoother - Gets the smoother on a particular cycle level. 423 424 Logically Collective on SNES 425 426 Input Parameters: 427 . snes - the multigrid context 428 429 Output Parameters: 430 . smooth - the smoother 431 432 Level: advanced 433 434 .keywords: SNES, FAS, get, smoother, multigrid 435 436 .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmootherDown() 437 @*/ 438 PetscErrorCode SNESFASCycleGetSmoother(SNES snes, SNES *smooth) 439 { 440 SNES_FAS *fas; 441 PetscFunctionBegin; 442 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 443 fas = (SNES_FAS*)snes->data; 444 *smooth = fas->smoothd; 445 PetscFunctionReturn(0); 446 } 447 #undef __FUNCT__ 448 #define __FUNCT__ "SNESFASCycleGetSmootherUp" 449 /*@ 450 SNESFASCycleGetSmootherUp - Gets the up smoother on a particular cycle level. 451 452 Logically Collective on SNES 453 454 Input Parameters: 455 . snes - the multigrid context 456 457 Output Parameters: 458 . smoothu - the smoother 459 460 Notes: 461 Returns the downsmoother if no up smoother is available. This enables transparent 462 default behavior in the process of the solve. 463 464 Level: advanced 465 466 .keywords: SNES, FAS, get, smoother, multigrid 467 468 .seealso: SNESFASCycleGetSmoother(), SNESFASCycleGetSmootherDown() 469 @*/ 470 PetscErrorCode SNESFASCycleGetSmootherUp(SNES snes, SNES *smoothu) 471 { 472 SNES_FAS *fas; 473 PetscFunctionBegin; 474 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 475 fas = (SNES_FAS*)snes->data; 476 if (!fas->smoothu) { 477 *smoothu = fas->smoothd; 478 } else { 479 *smoothu = fas->smoothu; 480 } 481 PetscFunctionReturn(0); 482 } 483 484 #undef __FUNCT__ 485 #define __FUNCT__ "SNESFASCycleGetSmootherDown" 486 /*@ 487 SNESFASCycleGetSmootherDown - Gets the down smoother on a particular cycle level. 488 489 Logically Collective on SNES 490 491 Input Parameters: 492 . snes - the multigrid context 493 494 Output Parameters: 495 . smoothd - the smoother 496 497 Level: advanced 498 499 .keywords: SNES, FAS, get, smoother, multigrid 500 501 .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother() 502 @*/ 503 PetscErrorCode SNESFASCycleGetSmootherDown(SNES snes, SNES *smoothd) 504 { 505 SNES_FAS *fas; 506 PetscFunctionBegin; 507 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 508 fas = (SNES_FAS*)snes->data; 509 *smoothd = fas->smoothd; 510 PetscFunctionReturn(0); 511 } 512 513 514 #undef __FUNCT__ 515 #define __FUNCT__ "SNESFASCycleGetCorrection" 516 /*@ 517 SNESFASCycleGetCorrection - Gets the coarse correction FAS context for this level 518 519 Logically Collective on SNES 520 521 Input Parameters: 522 . snes - the multigrid context 523 524 Output Parameters: 525 . correction - the coarse correction on this level 526 527 Notes: 528 Returns PETSC_NULL on the coarsest level. 529 530 Level: advanced 531 532 .keywords: SNES, FAS, get, smoother, multigrid 533 534 .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother() 535 @*/ 536 PetscErrorCode SNESFASCycleGetCorrection(SNES snes, SNES *correction) 537 { 538 SNES_FAS *fas; 539 PetscFunctionBegin; 540 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 541 fas = (SNES_FAS*)snes->data; 542 *correction = fas->next; 543 PetscFunctionReturn(0); 544 } 545 546 #undef __FUNCT__ 547 #define __FUNCT__ "SNESFASCycleGetInterpolation" 548 /*@ 549 SNESFASCycleGetInterpolation - Gets the interpolation on this level 550 551 Logically Collective on SNES 552 553 Input Parameters: 554 . snes - the multigrid context 555 556 Output Parameters: 557 . mat - the interpolation operator on this level 558 559 Level: developer 560 561 .keywords: SNES, FAS, get, smoother, multigrid 562 563 .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother() 564 @*/ 565 PetscErrorCode SNESFASCycleGetInterpolation(SNES snes, Mat *mat) 566 { 567 SNES_FAS *fas; 568 PetscFunctionBegin; 569 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 570 fas = (SNES_FAS*)snes->data; 571 *mat = fas->interpolate; 572 PetscFunctionReturn(0); 573 } 574 575 576 #undef __FUNCT__ 577 #define __FUNCT__ "SNESFASCycleGetRestriction" 578 /*@ 579 SNESFASCycleGetRestriction - Gets the restriction on this level 580 581 Logically Collective on SNES 582 583 Input Parameters: 584 . snes - the multigrid context 585 586 Output Parameters: 587 . mat - the restriction operator on this level 588 589 Level: developer 590 591 .keywords: SNES, FAS, get, smoother, multigrid 592 593 .seealso: SNESFASGetRestriction(), SNESFASCycleGetInterpolation() 594 @*/ 595 PetscErrorCode SNESFASCycleGetRestriction(SNES snes, Mat *mat) 596 { 597 SNES_FAS *fas; 598 PetscFunctionBegin; 599 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 600 fas = (SNES_FAS*)snes->data; 601 *mat = fas->restrct; 602 PetscFunctionReturn(0); 603 } 604 605 606 #undef __FUNCT__ 607 #define __FUNCT__ "SNESFASCycleGetInjection" 608 /*@ 609 SNESFASCycleGetInjection - Gets the injection on this level 610 611 Logically Collective on SNES 612 613 Input Parameters: 614 . snes - the multigrid context 615 616 Output Parameters: 617 . mat - the restriction operator on this level 618 619 Level: developer 620 621 .keywords: SNES, FAS, get, smoother, multigrid 622 623 .seealso: SNESFASGetInjection(), SNESFASCycleGetRestriction() 624 @*/ 625 PetscErrorCode SNESFASCycleGetInjection(SNES snes, Mat *mat) 626 { 627 SNES_FAS *fas; 628 PetscFunctionBegin; 629 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 630 fas = (SNES_FAS*)snes->data; 631 *mat = fas->inject; 632 PetscFunctionReturn(0); 633 } 634 635 #undef __FUNCT__ 636 #define __FUNCT__ "SNESFASCycleGetRScale" 637 /*@ 638 SNESFASCycleGetRScale - Gets the injection on this level 639 640 Logically Collective on SNES 641 642 Input Parameters: 643 . snes - the multigrid context 644 645 Output Parameters: 646 . mat - the restriction operator on this level 647 648 Level: developer 649 650 .keywords: SNES, FAS, get, smoother, multigrid 651 652 .seealso: SNESFASCycleGetRestriction(), SNESFASGetRScale() 653 @*/ 654 PetscErrorCode SNESFASCycleGetRScale(SNES snes, Vec *vec) 655 { 656 SNES_FAS *fas; 657 PetscFunctionBegin; 658 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 659 fas = (SNES_FAS*)snes->data; 660 *vec = fas->rscale; 661 PetscFunctionReturn(0); 662 } 663 664 #undef __FUNCT__ 665 #define __FUNCT__ "SNESFASCycleIsFine" 666 /*@ 667 SNESFASCycleIsFine - Determines if a given cycle is the fine level. 668 669 Logically Collective on SNES 670 671 Input Parameters: 672 . snes - the FAS context 673 674 Output Parameters: 675 . flg - indicates if this is the fine level or not 676 677 Level: advanced 678 679 .keywords: SNES, FAS 680 681 .seealso: SNESFASSetLevels() 682 @*/ 683 PetscErrorCode SNESFASCycleIsFine(SNES snes, PetscBool *flg) 684 { 685 SNES_FAS *fas; 686 PetscFunctionBegin; 687 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 688 fas = (SNES_FAS*)snes->data; 689 if (fas->level == fas->levels - 1) { 690 *flg = PETSC_TRUE; 691 } else { 692 *flg = PETSC_FALSE; 693 } 694 PetscFunctionReturn(0); 695 } 696 697 /* ---------- functions called on the finest level that return level-specific information ---------- */ 698 699 #undef __FUNCT__ 700 #define __FUNCT__ "SNESFASSetInterpolation" 701 /*@ 702 SNESFASSetInterpolation - Sets the function to be used to calculate the 703 interpolation from l-1 to the lth level 704 705 Input Parameters: 706 + snes - the multigrid context 707 . mat - the interpolation operator 708 - level - the level (0 is coarsest) to supply [do not supply 0] 709 710 Level: advanced 711 712 Notes: 713 Usually this is the same matrix used also to set the restriction 714 for the same level. 715 716 One can pass in the interpolation matrix or its transpose; PETSc figures 717 out from the matrix size which one it is. 718 719 .keywords: FAS, multigrid, set, interpolate, level 720 721 .seealso: SNESFASSetInjection(), SNESFASSetRestriction(), SNESFASSetRScale() 722 @*/ 723 PetscErrorCode SNESFASSetInterpolation(SNES snes, PetscInt level, Mat mat) { 724 SNES_FAS *fas = (SNES_FAS *)snes->data; 725 PetscErrorCode ierr; 726 SNES levelsnes; 727 PetscFunctionBegin; 728 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 729 fas = (SNES_FAS *)levelsnes->data; 730 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 731 ierr = MatDestroy(&fas->interpolate);CHKERRQ(ierr); 732 fas->interpolate = mat; 733 PetscFunctionReturn(0); 734 } 735 736 #undef __FUNCT__ 737 #define __FUNCT__ "SNESFASGetInterpolation" 738 /*@ 739 SNESFASGetInterpolation - Gets the matrix used to calculate the 740 interpolation from l-1 to the lth level 741 742 Input Parameters: 743 + snes - the multigrid context 744 - level - the level (0 is coarsest) to supply [do not supply 0] 745 746 Output Parameters: 747 . mat - the interpolation operator 748 749 Level: advanced 750 751 .keywords: FAS, multigrid, get, interpolate, level 752 753 .seealso: SNESFASSetInterpolation(), SNESFASGetInjection(), SNESFASGetRestriction(), SNESFASGetRScale() 754 @*/ 755 PetscErrorCode SNESFASGetInterpolation(SNES snes, PetscInt level, Mat *mat) { 756 SNES_FAS *fas = (SNES_FAS *)snes->data; 757 PetscErrorCode ierr; 758 SNES levelsnes; 759 PetscFunctionBegin; 760 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 761 fas = (SNES_FAS *)levelsnes->data; 762 *mat = fas->interpolate; 763 PetscFunctionReturn(0); 764 } 765 766 #undef __FUNCT__ 767 #define __FUNCT__ "SNESFASSetRestriction" 768 /*@ 769 SNESFASSetRestriction - Sets the function to be used to restrict the defect 770 from level l to l-1. 771 772 Input Parameters: 773 + snes - the multigrid context 774 . mat - the restriction matrix 775 - level - the level (0 is coarsest) to supply [Do not supply 0] 776 777 Level: advanced 778 779 Notes: 780 Usually this is the same matrix used also to set the interpolation 781 for the same level. 782 783 One can pass in the interpolation matrix or its transpose; PETSc figures 784 out from the matrix size which one it is. 785 786 If you do not set this, the transpose of the Mat set with SNESFASSetInterpolation() 787 is used. 788 789 .keywords: FAS, MG, set, multigrid, restriction, level 790 791 .seealso: SNESFASSetInterpolation(), SNESFASSetInjection() 792 @*/ 793 PetscErrorCode SNESFASSetRestriction(SNES snes, PetscInt level, Mat mat) { 794 SNES_FAS * fas = (SNES_FAS *)snes->data; 795 PetscErrorCode ierr; 796 SNES levelsnes; 797 PetscFunctionBegin; 798 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 799 fas = (SNES_FAS *)levelsnes->data; 800 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 801 ierr = MatDestroy(&fas->restrct);CHKERRQ(ierr); 802 fas->restrct = mat; 803 PetscFunctionReturn(0); 804 } 805 806 #undef __FUNCT__ 807 #define __FUNCT__ "SNESFASGetRestriction" 808 /*@ 809 SNESFASGetRestriction - Gets the matrix used to calculate the 810 restriction from l to the l-1th level 811 812 Input Parameters: 813 + snes - the multigrid context 814 - level - the level (0 is coarsest) to supply [do not supply 0] 815 816 Output Parameters: 817 . mat - the interpolation operator 818 819 Level: advanced 820 821 .keywords: FAS, multigrid, get, restrict, level 822 823 .seealso: SNESFASSetRestriction(), SNESFASGetInjection(), SNESFASGetInterpolation(), SNESFASGetRScale() 824 @*/ 825 PetscErrorCode SNESFASGetRestriction(SNES snes, PetscInt level, Mat *mat) { 826 SNES_FAS *fas = (SNES_FAS *)snes->data; 827 PetscErrorCode ierr; 828 SNES levelsnes; 829 PetscFunctionBegin; 830 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 831 fas = (SNES_FAS *)levelsnes->data; 832 *mat = fas->restrct; 833 PetscFunctionReturn(0); 834 } 835 836 837 #undef __FUNCT__ 838 #define __FUNCT__ "SNESFASSetInjection" 839 /*@ 840 SNESFASSetInjection - Sets the function to be used to inject the solution 841 from level l to l-1. 842 843 Input Parameters: 844 + snes - the multigrid context 845 . mat - the restriction matrix 846 - level - the level (0 is coarsest) to supply [Do not supply 0] 847 848 Level: advanced 849 850 Notes: 851 If you do not set this, the restriction and rscale is used to 852 project the solution instead. 853 854 .keywords: FAS, MG, set, multigrid, restriction, level 855 856 .seealso: SNESFASSetInterpolation(), SNESFASSetRestriction() 857 @*/ 858 PetscErrorCode SNESFASSetInjection(SNES snes, PetscInt level, Mat mat) { 859 SNES_FAS *fas = (SNES_FAS *)snes->data; 860 PetscErrorCode ierr; 861 SNES levelsnes; 862 PetscFunctionBegin; 863 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 864 fas = (SNES_FAS *)levelsnes->data; 865 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 866 ierr = MatDestroy(&fas->inject);CHKERRQ(ierr); 867 fas->inject = mat; 868 PetscFunctionReturn(0); 869 } 870 871 872 #undef __FUNCT__ 873 #define __FUNCT__ "SNESFASGetInjection" 874 /*@ 875 SNESFASGetInjection - Gets the matrix used to calculate the 876 injection from l-1 to the lth level 877 878 Input Parameters: 879 + snes - the multigrid context 880 - level - the level (0 is coarsest) to supply [do not supply 0] 881 882 Output Parameters: 883 . mat - the injection operator 884 885 Level: advanced 886 887 .keywords: FAS, multigrid, get, restrict, level 888 889 .seealso: SNESFASSetInjection(), SNESFASGetRestriction(), SNESFASGetInterpolation(), SNESFASGetRScale() 890 @*/ 891 PetscErrorCode SNESFASGetInjection(SNES snes, PetscInt level, Mat *mat) { 892 SNES_FAS *fas = (SNES_FAS *)snes->data; 893 PetscErrorCode ierr; 894 SNES levelsnes; 895 PetscFunctionBegin; 896 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 897 fas = (SNES_FAS *)levelsnes->data; 898 *mat = fas->inject; 899 PetscFunctionReturn(0); 900 } 901 902 #undef __FUNCT__ 903 #define __FUNCT__ "SNESFASSetRScale" 904 /*@ 905 SNESFASSetRScale - Sets the scaling factor of the restriction 906 operator from level l to l-1. 907 908 Input Parameters: 909 + snes - the multigrid context 910 . rscale - the restriction scaling 911 - level - the level (0 is coarsest) to supply [Do not supply 0] 912 913 Level: advanced 914 915 Notes: 916 This is only used in the case that the injection is not set. 917 918 .keywords: FAS, MG, set, multigrid, restriction, level 919 920 .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 921 @*/ 922 PetscErrorCode SNESFASSetRScale(SNES snes, PetscInt level, Vec rscale) { 923 SNES_FAS * fas; 924 PetscErrorCode ierr; 925 SNES levelsnes; 926 PetscFunctionBegin; 927 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 928 fas = (SNES_FAS *)levelsnes->data; 929 ierr = PetscObjectReference((PetscObject)rscale);CHKERRQ(ierr); 930 ierr = VecDestroy(&fas->rscale);CHKERRQ(ierr); 931 fas->rscale = rscale; 932 PetscFunctionReturn(0); 933 } 934 935 #undef __FUNCT__ 936 #define __FUNCT__ "SNESFASGetSmoother" 937 /*@ 938 SNESFASGetSmoother - Gets the default smoother on a level. 939 940 Input Parameters: 941 + snes - the multigrid context 942 - level - the level (0 is coarsest) to supply 943 944 Output Parameters: 945 smooth - the smoother 946 947 Level: advanced 948 949 .keywords: FAS, MG, get, multigrid, smoother, level 950 951 .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 952 @*/ 953 PetscErrorCode SNESFASGetSmoother(SNES snes, PetscInt level, SNES *smooth) { 954 SNES_FAS * fas; 955 PetscErrorCode ierr; 956 SNES levelsnes; 957 PetscFunctionBegin; 958 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 959 fas = (SNES_FAS *)levelsnes->data; 960 if (!fas->smoothd) { 961 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);CHKERRQ(ierr); 962 } 963 *smooth = fas->smoothd; 964 PetscFunctionReturn(0); 965 } 966 967 #undef __FUNCT__ 968 #define __FUNCT__ "SNESFASGetSmootherDown" 969 /*@ 970 SNESFASGetSmootherDown - Gets the downsmoother on a level. 971 972 Input Parameters: 973 + snes - the multigrid context 974 - level - the level (0 is coarsest) to supply 975 976 Output Parameters: 977 smooth - the smoother 978 979 Level: advanced 980 981 .keywords: FAS, MG, get, multigrid, smoother, level 982 983 .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 984 @*/ 985 PetscErrorCode SNESFASGetSmootherDown(SNES snes, PetscInt level, SNES *smooth) { 986 SNES_FAS * fas; 987 PetscErrorCode ierr; 988 SNES levelsnes; 989 PetscFunctionBegin; 990 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 991 fas = (SNES_FAS *)levelsnes->data; 992 /* if the user chooses to differentiate smoothers, create them both at this point */ 993 if (!fas->smoothd) { 994 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);CHKERRQ(ierr); 995 } 996 if (!fas->smoothu) { 997 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);CHKERRQ(ierr); 998 } 999 *smooth = fas->smoothd; 1000 PetscFunctionReturn(0); 1001 } 1002 1003 #undef __FUNCT__ 1004 #define __FUNCT__ "SNESFASGetSmootherUp" 1005 /*@ 1006 SNESFASGetSmootherUp - Gets the upsmoother on a level. 1007 1008 Input Parameters: 1009 + snes - the multigrid context 1010 - level - the level (0 is coarsest) 1011 1012 Output Parameters: 1013 smooth - the smoother 1014 1015 Level: advanced 1016 1017 .keywords: FAS, MG, get, multigrid, smoother, level 1018 1019 .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 1020 @*/ 1021 PetscErrorCode SNESFASGetSmootherUp(SNES snes, PetscInt level, SNES *smooth) { 1022 SNES_FAS * fas; 1023 PetscErrorCode ierr; 1024 SNES levelsnes; 1025 PetscFunctionBegin; 1026 ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 1027 fas = (SNES_FAS *)levelsnes->data; 1028 /* if the user chooses to differentiate smoothers, create them both at this point */ 1029 if (!fas->smoothd) { 1030 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);CHKERRQ(ierr); 1031 } 1032 if (!fas->smoothu) { 1033 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);CHKERRQ(ierr); 1034 } 1035 *smooth = fas->smoothu; 1036 PetscFunctionReturn(0); 1037 } 1038 1039 #undef __FUNCT__ 1040 #define __FUNCT__ "SNESFASGetCoarseSolve" 1041 /*@ 1042 SNESFASGetCoarseSolve - Gets the coarsest solver. 1043 1044 Input Parameters: 1045 + snes - the multigrid context 1046 1047 Output Parameters: 1048 solve - the coarse-level solver 1049 1050 Level: advanced 1051 1052 .keywords: FAS, MG, get, multigrid, solver, coarse 1053 1054 .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 1055 @*/ 1056 PetscErrorCode SNESFASGetCoarseSolve(SNES snes, SNES *smooth) { 1057 SNES_FAS * fas; 1058 PetscErrorCode ierr; 1059 SNES levelsnes; 1060 PetscFunctionBegin; 1061 ierr = SNESFASGetCycleSNES(snes, 0, &levelsnes);CHKERRQ(ierr); 1062 fas = (SNES_FAS *)levelsnes->data; 1063 /* if the user chooses to differentiate smoothers, create them both at this point */ 1064 if (!fas->smoothd) { 1065 ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);CHKERRQ(ierr); 1066 } 1067 *smooth = fas->smoothd; 1068 PetscFunctionReturn(0); 1069 } 1070