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