Actual source code: fasfunc.c
petsc-3.6.4 2016-04-12
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: }