Date: 2015-10-02T22:24:09+00:00

Actual source code: fasfunc.c
petsc-3.6.2 2015-10-02
Report Typos and Errors

      1: #include <../src/snes/impls/fas/fasimpls.h> /*I  "petscsnes.h"  I*/

      4: extern PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES, SNES*);

      6: /* -------------- functions called on the fine level -------------- */

     10: /*@
     11:     SNESFASSetType - Sets the update and correction type used for FAS.

     13:    Logically Collective

     15: Input Parameters:
     16: + snes  - FAS context
     17: - fastype  - SNES_FAS_ADDITIVE, SNES_FAS_MULTIPLICATIVE, SNES_FAS_FULL, or SNES_FAS_KASKADE

     19: Level: intermediate

     21: .seealso: PCMGSetType()
     22: @*/
     23: PetscErrorCode  SNESFASSetType(SNES snes,SNESFASType fastype)
     24: {
     25:   SNES_FAS       *fas = (SNES_FAS*)snes->data;

     31:   fas->fastype = fastype;
     32:   if (fas->next) {
     33:     SNESFASSetType(fas->next, fastype);
     34:   }
     35:   return(0);
     36: }

     41: /*@
     42: SNESFASGetType - Sets the update and correction type used for FAS.

     44: Logically Collective

     46: Input Parameters:
     47: . snes - FAS context

     49: Output Parameters:
     50: . fastype - SNES_FAS_ADDITIVE or SNES_FAS_MULTIPLICATIVE

     52: Level: intermediate

     54: .seealso: PCMGSetType()
     55: @*/
     56: PetscErrorCode  SNESFASGetType(SNES snes,SNESFASType *fastype)
     57: {
     58:   SNES_FAS *fas = (SNES_FAS*)snes->data;

     63:   *fastype = fas->fastype;
     64:   return(0);
     65: }

     69: /*@C
     70:    SNESFASSetLevels - Sets the number of levels to use with FAS.
     71:    Must be called before any other FAS routine.

     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 NULL_OBJECT for default in
     78:             Fortran.

     80:    Level: intermediate

     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.

     86: .keywords: FAS, MG, set, levels, multigrid

     88: .seealso: SNESFASGetLevels()
     89: @*/
     90: PetscErrorCode SNESFASSetLevels(SNES snes, PetscInt levels, MPI_Comm * comms)
     91: {
     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;

    101:   PetscObjectGetComm((PetscObject)snes,&comm);
    102:   if (levels == fas->levels) {
    103:     if (!comms) return(0);
    104:   }
    105:   /* user has changed the number of levels; reset */
    106:   SNESReset(snes);
    107:   /* destroy any coarser levels if necessary */
    108:   if (fas->next) SNESDestroy(&fas->next);
    109:   fas->next     = NULL;
    110:   fas->previous = NULL;
    111:   prevsnes      = snes;
    112:   /* setup the finest level */
    113:   SNESGetOptionsPrefix(snes, &optionsprefix);
    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   = NULL;
    120:     if (i > 0) {
    121:       SNESCreate(comm, &fas->next);
    122:       SNESGetOptionsPrefix(fas->fine, &optionsprefix);
    123:       sprintf(tprefix,"fas_levels_%d_cycle_",(int)fas->level);
    124:       SNESAppendOptionsPrefix(fas->next,optionsprefix);
    125:       SNESAppendOptionsPrefix(fas->next,tprefix);
    126:       SNESSetType(fas->next, SNESFAS);
    127:       SNESSetTolerances(fas->next, fas->next->abstol, fas->next->rtol, fas->next->stol, fas->n_cycles, fas->next->max_funcs);
    128:       PetscObjectIncrementTabLevel((PetscObject)fas->next, (PetscObject)snes, levels - i);

    130:       ((SNES_FAS*)fas->next->data)->previous = prevsnes;

    132:       prevsnes = fas->next;
    133:       fas      = (SNES_FAS*)prevsnes->data;
    134:     }
    135:   }
    136:   return(0);
    137: }

    142: /*@
    143:    SNESFASGetLevels - Gets the number of levels in a FAS, including fine and coarse grids

    145:    Input Parameter:
    146: .  snes - the nonlinear solver context

    148:    Output parameter:
    149: .  levels - the number of levels

    151:    Level: advanced

    153: .keywords: MG, get, levels, multigrid

    155: .seealso: SNESFASSetLevels(), PCMGGetLevels()
    156: @*/
    157: PetscErrorCode SNESFASGetLevels(SNES snes, PetscInt *levels)
    158: {
    159:   SNES_FAS * fas = (SNES_FAS*)snes->data;

    162:   *levels = fas->levels;
    163:   return(0);
    164: }

    169: /*@
    170:    SNESFASGetCycleSNES - Gets the SNES corresponding to a particular
    171:    level of the FAS hierarchy.

    173:    Input Parameters:
    174: +  snes    - the multigrid context
    175:    level   - the level to get
    176: -  lsnes   - whether to use the nonlinear smoother or not

    178:    Level: advanced

    180: .keywords: FAS, MG, set, cycles, Gauss-Seidel, multigrid

    182: .seealso: SNESFASSetLevels(), SNESFASGetLevels()
    183: @*/
    184: PetscErrorCode SNESFASGetCycleSNES(SNES snes,PetscInt level,SNES *lsnes)
    185: {
    186:   SNES_FAS *fas = (SNES_FAS*)snes->data;
    187:   PetscInt i;

    190:   if (level > fas->levels-1) SETERRQ2(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Requested level %D from SNESFAS containing %D levels",level,fas->levels);
    191:   if (fas->level !=  fas->levels - 1) SETERRQ2(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"SNESFASGetCycleSNES may only be called on the finest-level SNES.",level,fas->level);

    193:   *lsnes = snes;
    194:   for (i = fas->level; i > level; i--) {
    195:     *lsnes = fas->next;
    196:     fas    = (SNES_FAS*)(*lsnes)->data;
    197:   }
    198:   if (fas->level != level) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"SNESFAS level hierarchy corrupt");
    199:   return(0);
    200: }

    204: /*@
    205:    SNESFASSetNumberSmoothUp - Sets the number of post-smoothing steps to
    206:    use on all levels.

    208:    Logically Collective on SNES

    210:    Input Parameters:
    211: +  snes - the multigrid context
    212: -  n    - the number of smoothing steps

    214:    Options Database Key:
    215: .  -snes_fas_smoothup <n> - Sets number of pre-smoothing steps

    217:    Level: advanced

    219: .keywords: FAS, MG, smooth, down, pre-smoothing, steps, multigrid

    221: .seealso: SNESFASSetNumberSmoothDown()
    222: @*/
    223: PetscErrorCode SNESFASSetNumberSmoothUp(SNES snes, PetscInt n)
    224: {
    225:   SNES_FAS       *fas =  (SNES_FAS*)snes->data;

    229:   fas->max_up_it = n;
    230:   if (!fas->smoothu && fas->level != 0) {
    231:     SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);
    232:   }
    233:   if (fas->smoothu) {
    234:     SNESSetTolerances(fas->smoothu, fas->smoothu->abstol, fas->smoothu->rtol, fas->smoothu->stol, n, fas->smoothu->max_funcs);
    235:   }
    236:   if (fas->next) {
    237:     SNESFASSetNumberSmoothUp(fas->next, n);
    238:   }
    239:   return(0);
    240: }

    244: /*@
    245:    SNESFASSetNumberSmoothDown - Sets the number of pre-smoothing steps to
    246:    use on all levels.

    248:    Logically Collective on SNES

    250:    Input Parameters:
    251: +  snes - the multigrid context
    252: -  n    - the number of smoothing steps

    254:    Options Database Key:
    255: .  -snes_fas_smoothdown <n> - Sets number of pre-smoothing steps

    257:    Level: advanced

    259: .keywords: FAS, MG, smooth, down, pre-smoothing, steps, multigrid

    261: .seealso: SNESFASSetNumberSmoothUp()
    262: @*/
    263: PetscErrorCode SNESFASSetNumberSmoothDown(SNES snes, PetscInt n)
    264: {
    265:   SNES_FAS       *fas =  (SNES_FAS*)snes->data;
    266:   PetscErrorCode 0;

    269:   if (!fas->smoothd) {
    270:     SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);
    271:   }
    272:   SNESSetTolerances(fas->smoothd, fas->smoothd->abstol, fas->smoothd->rtol, fas->smoothd->stol, n, fas->smoothd->max_funcs);

    274:   fas->max_down_it = n;
    275:   if (fas->next) {
    276:     SNESFASSetNumberSmoothDown(fas->next, n);
    277:   }
    278:   return(0);
    279: }

    284: /*@
    285:    SNESFASSetContinuation - Sets the FAS cycle to default to exact Newton solves on the upsweep

    287:    Logically Collective on SNES

    289:    Input Parameters:
    290: +  snes - the multigrid context
    291: -  n    - the number of smoothing steps

    293:    Options Database Key:
    294: .  -snes_fas_continuation - sets continuation to true

    296:    Level: advanced

    298:    Notes: This sets the prefix on the upsweep smoothers to -fas_continuation

    300: .keywords: FAS, MG, smoother, continuation

    302: .seealso: SNESFAS
    303: @*/
    304: PetscErrorCode SNESFASSetContinuation(SNES snes,PetscBool continuation)
    305: {
    306:   const char     *optionsprefix;
    307:   char           tprefix[128];
    308:   SNES_FAS       *fas =  (SNES_FAS*)snes->data;
    309:   PetscErrorCode 0;

    312:   SNESGetOptionsPrefix(fas->fine, &optionsprefix);
    313:   if (!fas->smoothu) {
    314:     SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);
    315:   }
    316:   sprintf(tprefix,"fas_levels_continuation_");
    317:   SNESSetOptionsPrefix(fas->smoothu, optionsprefix);
    318:   SNESAppendOptionsPrefix(fas->smoothu, tprefix);
    319:   SNESSetType(fas->smoothu,SNESNEWTONLS);
    320:   SNESSetTolerances(fas->smoothu,fas->fine->abstol,fas->fine->rtol,fas->fine->stol,50,100);
    321:   fas->continuation = continuation;
    322:   if (fas->next) {
    323:     SNESFASSetContinuation(fas->next,continuation);
    324:   }
    325:   return(0);
    326: }

    331: /*@
    332:    SNESFASSetCycles - Sets the number of FAS multigrid cycles to use each time a grid is visited.  Use SNESFASSetCyclesOnLevel() for more
    333:    complicated cycling.

    335:    Logically Collective on SNES

    337:    Input Parameters:
    338: +  snes   - the multigrid context
    339: -  cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle

    341:    Options Database Key:
    342: .  -snes_fas_cycles 1 or 2

    344:    Level: advanced

    346: .keywords: MG, set, cycles, V-cycle, W-cycle, multigrid

    348: .seealso: SNESFASSetCyclesOnLevel()
    349: @*/
    350: PetscErrorCode SNESFASSetCycles(SNES snes, PetscInt cycles)
    351: {
    352:   SNES_FAS       *fas = (SNES_FAS*)snes->data;
    354:   PetscBool      isFine;

    357:   SNESFASCycleIsFine(snes, &isFine);

    359:   fas->n_cycles = cycles;
    360:   if (!isFine) {
    361:     SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);
    362:   }
    363:   if (fas->next) {
    364:     SNESFASSetCycles(fas->next, cycles);
    365:   }
    366:   return(0);
    367: }

    372: /*@
    373:    SNESFASSetMonitor - Sets the method-specific cycle monitoring

    375:    Logically Collective on SNES

    377:    Input Parameters:
    378: +  snes   - the FAS context
    379: -  flg    - monitor or not

    381:    Level: advanced

    383: .keywords: FAS, monitor

    385: .seealso: SNESFASSetCyclesOnLevel()
    386: @*/
    387: PetscErrorCode SNESFASSetMonitor(SNES snes, PetscBool flg)
    388: {
    389:   SNES_FAS       *fas = (SNES_FAS*)snes->data;
    391:   PetscBool      isFine;
    392:   PetscInt       i, levels = fas->levels;
    393:   SNES           levelsnes;

    396:   SNESFASCycleIsFine(snes, &isFine);
    397:   if (isFine) {
    398:     for (i = 0; i < levels; i++) {
    399:       SNESFASGetCycleSNES(snes, i, &levelsnes);
    400:       fas  = (SNES_FAS*)levelsnes->data;
    401:       if (flg) {
    402:         fas->monitor = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)levelsnes));
    403:         /* set the monitors for the upsmoother and downsmoother */
    404:         SNESMonitorCancel(levelsnes);
    405:         SNESMonitorSet(levelsnes,SNESMonitorDefault,NULL,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    406:       } else if (i != fas->levels - 1) {
    407:         /* unset the monitors on the coarse levels */
    408:         SNESMonitorCancel(levelsnes);
    409:       }
    410:     }
    411:   }
    412:   return(0);
    413: }

    417: /*@
    418:    SNESFASSetLog - Sets or unsets time logging for various FAS stages on all levels

    420:    Logically Collective on SNES

    422:    Input Parameters:
    423: +  snes   - the FAS context
    424: -  flg    - monitor or not

    426:    Level: advanced

    428: .keywords: FAS, logging

    430: .seealso: SNESFASSetMonitor()
    431: @*/
    432: PetscErrorCode SNESFASSetLog(SNES snes, PetscBool flg)
    433: {
    434:   SNES_FAS       *fas = (SNES_FAS*)snes->data;
    436:   PetscBool      isFine;
    437:   PetscInt       i, levels = fas->levels;
    438:   SNES           levelsnes;
    439:   char           eventname[128];

    442:   SNESFASCycleIsFine(snes, &isFine);
    443:   if (isFine) {
    444:     for (i = 0; i < levels; i++) {
    445:       SNESFASGetCycleSNES(snes, i, &levelsnes);
    446:       fas  = (SNES_FAS*)levelsnes->data;
    447:       if (flg) {
    448:         sprintf(eventname,"FASSetup %d",(int)i);
    449:         PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsetup);
    450:         sprintf(eventname,"FASSmooth %d",(int)i);
    451:         PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsolve);
    452:         sprintf(eventname,"FASResid %d",(int)i);
    453:         PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventresidual);
    454:         if (i) {
    455:           sprintf(eventname,"FASInterp %d",(int)i);
    456:           PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventinterprestrict);
    457:         }
    458:       } else {
    459:         fas->eventsmoothsetup    = 0;
    460:         fas->eventsmoothsolve    = 0;
    461:         fas->eventresidual       = 0;
    462:         fas->eventinterprestrict = 0;
    463:       }
    464:     }
    465:   }
    466:   return(0);
    467: }

    471: /*
    472: Creates the default smoother type.

    474: This is SNESNRICHARDSON on each fine level and SNESNEWTONLS on the coarse level.

    476:  */
    477: PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES snes, SNES *smooth)
    478: {
    479:   SNES_FAS       *fas;
    480:   const char     *optionsprefix;
    481:   char           tprefix[128];
    483:   SNES           nsmooth;

    487:   fas  = (SNES_FAS*)snes->data;
    488:   SNESGetOptionsPrefix(fas->fine, &optionsprefix);
    489:   /* create the default smoother */
    490:   SNESCreate(PetscObjectComm((PetscObject)snes), &nsmooth);
    491:   if (fas->level == 0) {
    492:     sprintf(tprefix,"fas_coarse_");
    493:     SNESAppendOptionsPrefix(nsmooth, optionsprefix);
    494:     SNESAppendOptionsPrefix(nsmooth, tprefix);
    495:     SNESSetType(nsmooth, SNESNEWTONLS);
    496:     SNESSetTolerances(nsmooth, nsmooth->abstol, nsmooth->rtol, nsmooth->stol, nsmooth->max_its, nsmooth->max_funcs);
    497:   } else {
    498:     sprintf(tprefix,"fas_levels_%d_",(int)fas->level);
    499:     SNESAppendOptionsPrefix(nsmooth, optionsprefix);
    500:     SNESAppendOptionsPrefix(nsmooth, tprefix);
    501:     SNESSetType(nsmooth, SNESNRICHARDSON);
    502:     SNESSetTolerances(nsmooth, 0.0, 0.0, 0.0, fas->max_down_it, nsmooth->max_funcs);
    503:   }
    504:   PetscObjectIncrementTabLevel((PetscObject)nsmooth, (PetscObject)snes, 1);
    505:   PetscLogObjectParent((PetscObject)snes,(PetscObject)nsmooth);
    506:   PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)nsmooth);
    507:   *smooth = nsmooth;
    508:   return(0);
    509: }

    511: /* ------------- Functions called on a particular level ----------------- */

    515: /*@
    516:    SNESFASCycleSetCycles - Sets the number of cycles on a particular level.

    518:    Logically Collective on SNES

    520:    Input Parameters:
    521: +  snes   - the multigrid context
    522: .  level  - the level to set the number of cycles on
    523: -  cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle

    525:    Level: advanced

    527: .keywords: SNES, FAS, set, cycles, V-cycle, W-cycle, multigrid

    529: .seealso: SNESFASSetCycles()
    530: @*/
    531: PetscErrorCode SNESFASCycleSetCycles(SNES snes, PetscInt cycles)
    532: {
    533:   SNES_FAS       *fas =  (SNES_FAS*)snes->data;

    537:   fas->n_cycles = cycles;
    538:   SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);
    539:   return(0);
    540: }

    545: /*@
    546:    SNESFASCycleGetSmoother - Gets the smoother on a particular cycle level.

    548:    Logically Collective on SNES

    550:    Input Parameters:
    551: .  snes   - the multigrid context

    553:    Output Parameters:
    554: .  smooth - the smoother

    556:    Level: advanced

    558: .keywords: SNES, FAS, get, smoother, multigrid

    560: .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmootherDown()
    561: @*/
    562: PetscErrorCode SNESFASCycleGetSmoother(SNES snes, SNES *smooth)
    563: {
    564:   SNES_FAS *fas;

    568:   fas     = (SNES_FAS*)snes->data;
    569:   *smooth = fas->smoothd;
    570:   return(0);
    571: }
    574: /*@
    575:    SNESFASCycleGetSmootherUp - Gets the up smoother on a particular cycle level.

    577:    Logically Collective on SNES

    579:    Input Parameters:
    580: .  snes   - the multigrid context

    582:    Output Parameters:
    583: .  smoothu - the smoother

    585:    Notes:
    586:    Returns the downsmoother if no up smoother is available.  This enables transparent
    587:    default behavior in the process of the solve.

    589:    Level: advanced

    591: .keywords: SNES, FAS, get, smoother, multigrid

    593: .seealso: SNESFASCycleGetSmoother(), SNESFASCycleGetSmootherDown()
    594: @*/
    595: PetscErrorCode SNESFASCycleGetSmootherUp(SNES snes, SNES *smoothu)
    596: {
    597:   SNES_FAS *fas;

    601:   fas = (SNES_FAS*)snes->data;
    602:   if (!fas->smoothu) *smoothu = fas->smoothd;
    603:   else *smoothu = fas->smoothu;
    604:   return(0);
    605: }

    609: /*@
    610:    SNESFASCycleGetSmootherDown - Gets the down smoother on a particular cycle level.

    612:    Logically Collective on SNES

    614:    Input Parameters:
    615: .  snes   - the multigrid context

    617:    Output Parameters:
    618: .  smoothd - the smoother

    620:    Level: advanced

    622: .keywords: SNES, FAS, get, smoother, multigrid

    624: .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
    625: @*/
    626: PetscErrorCode SNESFASCycleGetSmootherDown(SNES snes, SNES *smoothd)
    627: {
    628:   SNES_FAS *fas;

    632:   fas      = (SNES_FAS*)snes->data;
    633:   *smoothd = fas->smoothd;
    634:   return(0);
    635: }

    640: /*@
    641:    SNESFASCycleGetCorrection - Gets the coarse correction FAS context for this level

    643:    Logically Collective on SNES

    645:    Input Parameters:
    646: .  snes   - the multigrid context

    648:    Output Parameters:
    649: .  correction - the coarse correction on this level

    651:    Notes:
    652:    Returns NULL on the coarsest level.

    654:    Level: advanced

    656: .keywords: SNES, FAS, get, smoother, multigrid

    658: .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
    659: @*/
    660: PetscErrorCode SNESFASCycleGetCorrection(SNES snes, SNES *correction)
    661: {
    662:   SNES_FAS *fas;

    666:   fas         = (SNES_FAS*)snes->data;
    667:   *correction = fas->next;
    668:   return(0);
    669: }

    673: /*@
    674:    SNESFASCycleGetInterpolation - Gets the interpolation on this level

    676:    Logically Collective on SNES

    678:    Input Parameters:
    679: .  snes   - the multigrid context

    681:    Output Parameters:
    682: .  mat    - the interpolation operator on this level

    684:    Level: developer

    686: .keywords: SNES, FAS, get, smoother, multigrid

    688: .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
    689: @*/
    690: PetscErrorCode SNESFASCycleGetInterpolation(SNES snes, Mat *mat)
    691: {
    692:   SNES_FAS *fas;

    696:   fas  = (SNES_FAS*)snes->data;
    697:   *mat = fas->interpolate;
    698:   return(0);
    699: }

    704: /*@
    705:    SNESFASCycleGetRestriction - Gets the restriction on this level

    707:    Logically Collective on SNES

    709:    Input Parameters:
    710: .  snes   - the multigrid context

    712:    Output Parameters:
    713: .  mat    - the restriction operator on this level

    715:    Level: developer

    717: .keywords: SNES, FAS, get, smoother, multigrid

    719: .seealso: SNESFASGetRestriction(), SNESFASCycleGetInterpolation()
    720: @*/
    721: PetscErrorCode SNESFASCycleGetRestriction(SNES snes, Mat *mat)
    722: {
    723:   SNES_FAS *fas;

    727:   fas  = (SNES_FAS*)snes->data;
    728:   *mat = fas->restrct;
    729:   return(0);
    730: }

    735: /*@
    736:    SNESFASCycleGetInjection - Gets the injection on this level

    738:    Logically Collective on SNES

    740:    Input Parameters:
    741: .  snes   - the multigrid context

    743:    Output Parameters:
    744: .  mat    - the restriction operator on this level

    746:    Level: developer

    748: .keywords: SNES, FAS, get, smoother, multigrid

    750: .seealso: SNESFASGetInjection(), SNESFASCycleGetRestriction()
    751: @*/
    752: PetscErrorCode SNESFASCycleGetInjection(SNES snes, Mat *mat)
    753: {
    754:   SNES_FAS *fas;

    758:   fas  = (SNES_FAS*)snes->data;
    759:   *mat = fas->inject;
    760:   return(0);
    761: }

    765: /*@
    766:    SNESFASCycleGetRScale - Gets the injection on this level

    768:    Logically Collective on SNES

    770:    Input Parameters:
    771: .  snes   - the multigrid context

    773:    Output Parameters:
    774: .  mat    - the restriction operator on this level

    776:    Level: developer

    778: .keywords: SNES, FAS, get, smoother, multigrid

    780: .seealso: SNESFASCycleGetRestriction(), SNESFASGetRScale()
    781: @*/
    782: PetscErrorCode SNESFASCycleGetRScale(SNES snes, Vec *vec)
    783: {
    784:   SNES_FAS *fas;

    788:   fas  = (SNES_FAS*)snes->data;
    789:   *vec = fas->rscale;
    790:   return(0);
    791: }

    795: /*@
    796:    SNESFASCycleIsFine - Determines if a given cycle is the fine level.

    798:    Logically Collective on SNES

    800:    Input Parameters:
    801: .  snes   - the FAS context

    803:    Output Parameters:
    804: .  flg - indicates if this is the fine level or not

    806:    Level: advanced

    808: .keywords: SNES, FAS

    810: .seealso: SNESFASSetLevels()
    811: @*/
    812: PetscErrorCode SNESFASCycleIsFine(SNES snes, PetscBool *flg)
    813: {
    814:   SNES_FAS *fas;

    818:   fas = (SNES_FAS*)snes->data;
    819:   if (fas->level == fas->levels - 1) *flg = PETSC_TRUE;
    820:   else *flg = PETSC_FALSE;
    821:   return(0);
    822: }

    824: /* ---------- functions called on the finest level that return level-specific information ---------- */

    828: /*@
    829:    SNESFASSetInterpolation - Sets the function to be used to calculate the
    830:    interpolation from l-1 to the lth level

    832:    Input Parameters:
    833: +  snes      - the multigrid context
    834: .  mat       - the interpolation operator
    835: -  level     - the level (0 is coarsest) to supply [do not supply 0]

    837:    Level: advanced

    839:    Notes:
    840:           Usually this is the same matrix used also to set the restriction
    841:     for the same level.

    843:           One can pass in the interpolation matrix or its transpose; PETSc figures
    844:     out from the matrix size which one it is.

    846: .keywords:  FAS, multigrid, set, interpolate, level

    848: .seealso: SNESFASSetInjection(), SNESFASSetRestriction(), SNESFASSetRScale()
    849: @*/
    850: PetscErrorCode SNESFASSetInterpolation(SNES snes, PetscInt level, Mat mat)
    851: {
    852:   SNES_FAS       *fas;
    854:   SNES           levelsnes;

    857:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    858:   fas  = (SNES_FAS*)levelsnes->data;
    859:   PetscObjectReference((PetscObject)mat);
    860:   MatDestroy(&fas->interpolate);

    862:   fas->interpolate = mat;
    863:   return(0);
    864: }

    868: /*@
    869:    SNESFASGetInterpolation - Gets the matrix used to calculate the
    870:    interpolation from l-1 to the lth level

    872:    Input Parameters:
    873: +  snes      - the multigrid context
    874: -  level     - the level (0 is coarsest) to supply [do not supply 0]

    876:    Output Parameters:
    877: .  mat       - the interpolation operator

    879:    Level: advanced

    881: .keywords:  FAS, multigrid, get, interpolate, level

    883: .seealso: SNESFASSetInterpolation(), SNESFASGetInjection(), SNESFASGetRestriction(), SNESFASGetRScale()
    884: @*/
    885: PetscErrorCode SNESFASGetInterpolation(SNES snes, PetscInt level, Mat *mat)
    886: {
    887:   SNES_FAS       *fas;
    889:   SNES           levelsnes;

    892:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    893:   fas  = (SNES_FAS*)levelsnes->data;
    894:   *mat = fas->interpolate;
    895:   return(0);
    896: }

    900: /*@
    901:    SNESFASSetRestriction - Sets the function to be used to restrict the defect
    902:    from level l to l-1.

    904:    Input Parameters:
    905: +  snes  - the multigrid context
    906: .  mat   - the restriction matrix
    907: -  level - the level (0 is coarsest) to supply [Do not supply 0]

    909:    Level: advanced

    911:    Notes:
    912:           Usually this is the same matrix used also to set the interpolation
    913:     for the same level.

    915:           One can pass in the interpolation matrix or its transpose; PETSc figures
    916:     out from the matrix size which one it is.

    918:          If you do not set this, the transpose of the Mat set with SNESFASSetInterpolation()
    919:     is used.

    921: .keywords: FAS, MG, set, multigrid, restriction, level

    923: .seealso: SNESFASSetInterpolation(), SNESFASSetInjection()
    924: @*/
    925: PetscErrorCode SNESFASSetRestriction(SNES snes, PetscInt level, Mat mat)
    926: {
    927:   SNES_FAS       *fas;
    929:   SNES           levelsnes;

    932:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    933:   fas  = (SNES_FAS*)levelsnes->data;
    934:   PetscObjectReference((PetscObject)mat);
    935:   MatDestroy(&fas->restrct);

    937:   fas->restrct = mat;
    938:   return(0);
    939: }

    943: /*@
    944:    SNESFASGetRestriction - Gets the matrix used to calculate the
    945:    restriction from l to the l-1th level

    947:    Input Parameters:
    948: +  snes      - the multigrid context
    949: -  level     - the level (0 is coarsest) to supply [do not supply 0]

    951:    Output Parameters:
    952: .  mat       - the interpolation operator

    954:    Level: advanced

    956: .keywords:  FAS, multigrid, get, restrict, level

    958: .seealso: SNESFASSetRestriction(), SNESFASGetInjection(), SNESFASGetInterpolation(), SNESFASGetRScale()
    959: @*/
    960: PetscErrorCode SNESFASGetRestriction(SNES snes, PetscInt level, Mat *mat)
    961: {
    962:   SNES_FAS       *fas;
    964:   SNES           levelsnes;

    967:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    968:   fas  = (SNES_FAS*)levelsnes->data;
    969:   *mat = fas->restrct;
    970:   return(0);
    971: }

    976: /*@
    977:    SNESFASSetInjection - Sets the function to be used to inject the solution
    978:    from level l to l-1.

    980:    Input Parameters:
    981:  +  snes  - the multigrid context
    982: .  mat   - the restriction matrix
    983: -  level - the level (0 is coarsest) to supply [Do not supply 0]

    985:    Level: advanced

    987:    Notes:
    988:          If you do not set this, the restriction and rscale is used to
    989:    project the solution instead.

    991: .keywords: FAS, MG, set, multigrid, restriction, level

    993: .seealso: SNESFASSetInterpolation(), SNESFASSetRestriction()
    994: @*/
    995: PetscErrorCode SNESFASSetInjection(SNES snes, PetscInt level, Mat mat)
    996: {
    997:   SNES_FAS       *fas;
    999:   SNES           levelsnes;

    1002:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    1003:   fas  = (SNES_FAS*)levelsnes->data;
    1004:   PetscObjectReference((PetscObject)mat);
    1005:   MatDestroy(&fas->inject);

    1007:   fas->inject = mat;
    1008:   return(0);
    1009: }

    1014: /*@
    1015:    SNESFASGetInjection - Gets the matrix used to calculate the
    1016:    injection from l-1 to the lth level

    1018:    Input Parameters:
    1019: +  snes      - the multigrid context
    1020: -  level     - the level (0 is coarsest) to supply [do not supply 0]

    1022:    Output Parameters:
    1023: .  mat       - the injection operator

    1025:    Level: advanced

    1027: .keywords:  FAS, multigrid, get, restrict, level

    1029: .seealso: SNESFASSetInjection(), SNESFASGetRestriction(), SNESFASGetInterpolation(), SNESFASGetRScale()
    1030: @*/
    1031: PetscErrorCode SNESFASGetInjection(SNES snes, PetscInt level, Mat *mat)
    1032: {
    1033:   SNES_FAS       *fas;
    1035:   SNES           levelsnes;

    1038:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    1039:   fas  = (SNES_FAS*)levelsnes->data;
    1040:   *mat = fas->inject;
    1041:   return(0);
    1042: }

    1046: /*@
    1047:    SNESFASSetRScale - Sets the scaling factor of the restriction
    1048:    operator from level l to l-1.

    1050:    Input Parameters:
    1051: +  snes   - the multigrid context
    1052: .  rscale - the restriction scaling
    1053: -  level  - the level (0 is coarsest) to supply [Do not supply 0]

    1055:    Level: advanced

    1057:    Notes:
    1058:          This is only used in the case that the injection is not set.

    1060: .keywords: FAS, MG, set, multigrid, restriction, level

    1062: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
    1063: @*/
    1064: PetscErrorCode SNESFASSetRScale(SNES snes, PetscInt level, Vec rscale)
    1065: {
    1066:   SNES_FAS       *fas;
    1068:   SNES           levelsnes;

    1071:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    1072:   fas  = (SNES_FAS*)levelsnes->data;
    1073:   PetscObjectReference((PetscObject)rscale);
    1074:   VecDestroy(&fas->rscale);

    1076:   fas->rscale = rscale;
    1077:   return(0);
    1078: }

    1082: /*@
    1083:    SNESFASGetSmoother - Gets the default smoother on a level.

    1085:    Input Parameters:
    1086: +  snes   - the multigrid context
    1087: -  level  - the level (0 is coarsest) to supply

    1089:    Output Parameters:
    1090:    smooth  - the smoother

    1092:    Level: advanced

    1094: .keywords: FAS, MG, get, multigrid, smoother, level

    1096: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
    1097: @*/
    1098: PetscErrorCode SNESFASGetSmoother(SNES snes, PetscInt level, SNES *smooth)
    1099: {
    1100:   SNES_FAS       *fas;
    1102:   SNES           levelsnes;

    1105:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    1106:   fas  = (SNES_FAS*)levelsnes->data;
    1107:   if (!fas->smoothd) {
    1108:     SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);
    1109:   }
    1110:   *smooth = fas->smoothd;
    1111:   return(0);
    1112: }

    1116: /*@
    1117:    SNESFASGetSmootherDown - Gets the downsmoother on a level.

    1119:    Input Parameters:
    1120: +  snes   - the multigrid context
    1121: -  level  - the level (0 is coarsest) to supply

    1123:    Output Parameters:
    1124:    smooth  - the smoother

    1126:    Level: advanced

    1128: .keywords: FAS, MG, get, multigrid, smoother, level

    1130: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
    1131: @*/
    1132: PetscErrorCode SNESFASGetSmootherDown(SNES snes, PetscInt level, SNES *smooth)
    1133: {
    1134:   SNES_FAS       *fas;
    1136:   SNES           levelsnes;

    1139:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    1140:   fas  = (SNES_FAS*)levelsnes->data;
    1141:   /* if the user chooses to differentiate smoothers, create them both at this point */
    1142:   if (!fas->smoothd) {
    1143:     SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);
    1144:   }
    1145:   if (!fas->smoothu) {
    1146:     SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);
    1147:   }
    1148:   *smooth = fas->smoothd;
    1149:   return(0);
    1150: }

    1154: /*@
    1155:    SNESFASGetSmootherUp - Gets the upsmoother on a level.

    1157:    Input Parameters:
    1158: +  snes   - the multigrid context
    1159: -  level  - the level (0 is coarsest)

    1161:    Output Parameters:
    1162:    smooth  - the smoother

    1164:    Level: advanced

    1166: .keywords: FAS, MG, get, multigrid, smoother, level

    1168: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
    1169: @*/
    1170: PetscErrorCode SNESFASGetSmootherUp(SNES snes, PetscInt level, SNES *smooth)
    1171: {
    1172:   SNES_FAS       *fas;
    1174:   SNES           levelsnes;

    1177:   SNESFASGetCycleSNES(snes, level, &levelsnes);
    1178:   fas  = (SNES_FAS*)levelsnes->data;
    1179:   /* if the user chooses to differentiate smoothers, create them both at this point */
    1180:   if (!fas->smoothd) {
    1181:     SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);
    1182:   }
    1183:   if (!fas->smoothu) {
    1184:     SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);
    1185:   }
    1186:   *smooth = fas->smoothu;
    1187:   return(0);
    1188: }

    1192: /*@
    1193:    SNESFASGetCoarseSolve - Gets the coarsest solver.

    1195:    Input Parameters:
    1196: +  snes   - the multigrid context

    1198:    Output Parameters:
    1199:    solve  - the coarse-level solver

    1201:    Level: advanced

    1203: .keywords: FAS, MG, get, multigrid, solver, coarse

    1205: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
    1206: @*/
    1207: PetscErrorCode SNESFASGetCoarseSolve(SNES snes, SNES *smooth)
    1208: {
    1209:   SNES_FAS       *fas;
    1211:   SNES           levelsnes;

    1214:   SNESFASGetCycleSNES(snes, 0, &levelsnes);
    1215:   fas  = (SNES_FAS*)levelsnes->data;
    1216:   /* if the user chooses to differentiate smoothers, create them both at this point */
    1217:   if (!fas->smoothd) {
    1218:     SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);
    1219:   }
    1220:   *smooth = fas->smoothd;
    1221:   return(0);
    1222: }

    1226: /*@
    1227:    SNESFASFullSetDownSweep - Smooth during the initial downsweep for SNESFAS

    1229:    Logically Collective on SNES

    1231:    Input Parameters:
    1232: +  snes - the multigrid context
    1233: -  swp - whether to downsweep or not

    1235:    Options Database Key:
    1236: .  -snes_fas_full_downsweep - Sets number of pre-smoothing steps

    1238:    Level: advanced

    1240: .keywords: FAS, MG, smooth, down, pre-smoothing, steps, multigrid

    1242: .seealso: SNESFASSetNumberSmoothUp()
    1243: @*/
    1244: PetscErrorCode SNESFASFullSetDownSweep(SNES snes,PetscBool swp)
    1245: {
    1246:   SNES_FAS       *fas =  (SNES_FAS*)snes->data;
    1247:   PetscErrorCode 0;

    1250:   fas->full_downsweep = swp;
    1251:   if (fas->next) {
    1252:     SNESFASFullSetDownSweep(fas->next,swp);
    1253:   }
    1254:   return(0);
    1255: }