Actual source code: fasfunc.c
1: #include <../src/snes/impls/fas/fasimpls.h>
3: /* -------------- functions called on the fine level -------------- */
5: /*@
6: SNESFASSetType - Sets the update and correction type used for FAS.
8: Logically Collective
10: Input Parameters:
11: + snes - FAS context
12: - fastype - SNES_FAS_ADDITIVE, SNES_FAS_MULTIPLICATIVE, SNES_FAS_FULL, or SNES_FAS_KASKADE
14: Level: intermediate
16: .seealso: PCMGSetType()
17: @*/
18: PetscErrorCode SNESFASSetType(SNES snes,SNESFASType fastype)
19: {
20: SNES_FAS *fas;
26: fas = (SNES_FAS*)snes->data;
27: fas->fastype = fastype;
28: if (fas->next) {
29: SNESFASSetType(fas->next, fastype);
30: }
31: return(0);
32: }
34: /*@
35: SNESFASGetType - Sets the update and correction type used for FAS.
37: Logically Collective
39: Input Parameters:
40: . snes - FAS context
42: Output Parameters:
43: . fastype - SNES_FAS_ADDITIVE or SNES_FAS_MULTIPLICATIVE
45: Level: intermediate
47: .seealso: PCMGSetType()
48: @*/
49: PetscErrorCode SNESFASGetType(SNES snes,SNESFASType *fastype)
50: {
51: SNES_FAS *fas;
56: fas = (SNES_FAS*)snes->data;
57: *fastype = fas->fastype;
58: return(0);
59: }
61: /*@C
62: SNESFASSetLevels - Sets the number of levels to use with FAS.
63: Must be called before any other FAS routine.
65: Input Parameters:
66: + snes - the snes context
67: . levels - the number of levels
68: - comms - optional communicators for each level; this is to allow solving the coarser
69: problems on smaller sets of processors.
71: Level: intermediate
73: Notes:
74: If the number of levels is one then the multigrid uses the -fas_levels prefix
75: for setting the level options rather than the -fas_coarse prefix.
77: .seealso: SNESFASGetLevels()
78: @*/
79: PetscErrorCode SNESFASSetLevels(SNES snes, PetscInt levels, MPI_Comm *comms)
80: {
82: PetscInt i;
83: const char *optionsprefix;
84: char tprefix[128];
85: SNES_FAS *fas;
86: SNES prevsnes;
87: MPI_Comm comm;
91: fas = (SNES_FAS*)snes->data;
92: PetscObjectGetComm((PetscObject)snes,&comm);
93: if (levels == fas->levels) {
94: if (!comms) return(0);
95: }
96: /* user has changed the number of levels; reset */
97: (*snes->ops->reset)(snes);
98: /* destroy any coarser levels if necessary */
99: SNESDestroy(&fas->next);
100: fas->next = NULL;
101: fas->previous = NULL;
102: prevsnes = snes;
103: /* setup the finest level */
104: SNESGetOptionsPrefix(snes, &optionsprefix);
105: PetscObjectComposedDataSetInt((PetscObject) snes, PetscMGLevelId, levels-1);
106: for (i = levels - 1; i >= 0; i--) {
107: if (comms) comm = comms[i];
108: fas->level = i;
109: fas->levels = levels;
110: fas->fine = snes;
111: fas->next = NULL;
112: if (i > 0) {
113: SNESCreate(comm, &fas->next);
114: SNESGetOptionsPrefix(fas->fine, &optionsprefix);
115: PetscSNPrintf(tprefix,sizeof(tprefix),"fas_levels_%d_cycle_",(int)fas->level);
116: SNESAppendOptionsPrefix(fas->next,optionsprefix);
117: SNESAppendOptionsPrefix(fas->next,tprefix);
118: SNESSetType(fas->next, SNESFAS);
119: SNESSetTolerances(fas->next, fas->next->abstol, fas->next->rtol, fas->next->stol, fas->n_cycles, fas->next->max_funcs);
120: PetscObjectIncrementTabLevel((PetscObject)fas->next, (PetscObject)snes, levels - i);
121: PetscObjectComposedDataSetInt((PetscObject) fas->next, PetscMGLevelId, i-1);
123: ((SNES_FAS*)fas->next->data)->previous = prevsnes;
125: prevsnes = fas->next;
126: fas = (SNES_FAS*)prevsnes->data;
127: }
128: }
129: return(0);
130: }
132: /*@
133: SNESFASGetLevels - Gets the number of levels in a FAS, including fine and coarse grids
135: Input Parameter:
136: . snes - the nonlinear solver context
138: Output parameter:
139: . levels - the number of levels
141: Level: advanced
143: .seealso: SNESFASSetLevels(), PCMGGetLevels()
144: @*/
145: PetscErrorCode SNESFASGetLevels(SNES snes, PetscInt *levels)
146: {
147: SNES_FAS *fas;
152: fas = (SNES_FAS*)snes->data;
153: *levels = fas->levels;
154: return(0);
155: }
157: /*@
158: SNESFASGetCycleSNES - Gets the SNES corresponding to a particular
159: level of the FAS hierarchy.
161: Input Parameters:
162: + snes - the multigrid context
163: level - the level to get
164: - lsnes - whether to use the nonlinear smoother or not
166: Level: advanced
168: .seealso: SNESFASSetLevels(), SNESFASGetLevels()
169: @*/
170: PetscErrorCode SNESFASGetCycleSNES(SNES snes,PetscInt level,SNES *lsnes)
171: {
172: SNES_FAS *fas;
173: PetscInt i;
178: fas = (SNES_FAS*)snes->data;
179: if (level > fas->levels-1) SETERRQ2(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Requested level %D from SNESFAS containing %D levels",level,fas->levels);
180: 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);
182: *lsnes = snes;
183: for (i = fas->level; i > level; i--) {
184: *lsnes = fas->next;
185: fas = (SNES_FAS*)(*lsnes)->data;
186: }
187: if (fas->level != level) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"SNESFAS level hierarchy corrupt");
188: return(0);
189: }
191: /*@
192: SNESFASSetNumberSmoothUp - Sets the number of post-smoothing steps to
193: use on all levels.
195: Logically Collective on SNES
197: Input Parameters:
198: + snes - the multigrid context
199: - n - the number of smoothing steps
201: Options Database Key:
202: . -snes_fas_smoothup <n> - Sets number of pre-smoothing steps
204: Level: advanced
206: .seealso: SNESFASSetNumberSmoothDown()
207: @*/
208: PetscErrorCode SNESFASSetNumberSmoothUp(SNES snes, PetscInt n)
209: {
210: SNES_FAS *fas;
215: fas = (SNES_FAS*)snes->data;
216: fas->max_up_it = n;
217: if (!fas->smoothu && fas->level != 0) {
218: SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);
219: }
220: if (fas->smoothu) {
221: SNESSetTolerances(fas->smoothu, fas->smoothu->abstol, fas->smoothu->rtol, fas->smoothu->stol, n, fas->smoothu->max_funcs);
222: }
223: if (fas->next) {
224: SNESFASSetNumberSmoothUp(fas->next, n);
225: }
226: return(0);
227: }
229: /*@
230: SNESFASSetNumberSmoothDown - Sets the number of pre-smoothing steps to
231: use on all levels.
233: Logically Collective on SNES
235: Input Parameters:
236: + snes - the multigrid context
237: - n - the number of smoothing steps
239: Options Database Key:
240: . -snes_fas_smoothdown <n> - Sets number of pre-smoothing steps
242: Level: advanced
244: .seealso: SNESFASSetNumberSmoothUp()
245: @*/
246: PetscErrorCode SNESFASSetNumberSmoothDown(SNES snes, PetscInt n)
247: {
248: SNES_FAS *fas;
253: fas = (SNES_FAS*)snes->data;
254: if (!fas->smoothd) {
255: SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);
256: }
257: SNESSetTolerances(fas->smoothd, fas->smoothd->abstol, fas->smoothd->rtol, fas->smoothd->stol, n, fas->smoothd->max_funcs);
259: fas->max_down_it = n;
260: if (fas->next) {
261: SNESFASSetNumberSmoothDown(fas->next, n);
262: }
263: return(0);
264: }
266: /*@
267: SNESFASSetContinuation - Sets the FAS cycle to default to exact Newton solves on the upsweep
269: Logically Collective on SNES
271: Input Parameters:
272: + snes - the multigrid context
273: - n - the number of smoothing steps
275: Options Database Key:
276: . -snes_fas_continuation - sets continuation to true
278: Level: advanced
280: Notes:
281: This sets the prefix on the upsweep smoothers to -fas_continuation
283: .seealso: SNESFAS
284: @*/
285: PetscErrorCode SNESFASSetContinuation(SNES snes,PetscBool continuation)
286: {
287: const char *optionsprefix;
288: char tprefix[128];
289: SNES_FAS *fas;
294: fas = (SNES_FAS*)snes->data;
295: SNESGetOptionsPrefix(fas->fine, &optionsprefix);
296: if (!fas->smoothu) {
297: SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);
298: }
299: PetscStrncpy(tprefix,"fas_levels_continuation_",sizeof(tprefix));
300: SNESSetOptionsPrefix(fas->smoothu, optionsprefix);
301: SNESAppendOptionsPrefix(fas->smoothu, tprefix);
302: SNESSetType(fas->smoothu,SNESNEWTONLS);
303: SNESSetTolerances(fas->smoothu,fas->fine->abstol,fas->fine->rtol,fas->fine->stol,50,100);
304: fas->continuation = continuation;
305: if (fas->next) {
306: SNESFASSetContinuation(fas->next,continuation);
307: }
308: return(0);
309: }
311: /*@
312: SNESFASSetCycles - Sets the number of FAS multigrid cycles to use each time a grid is visited. Use SNESFASSetCyclesOnLevel() for more
313: complicated cycling.
315: Logically Collective on SNES
317: Input Parameters:
318: + snes - the multigrid context
319: - cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle
321: Options Database Key:
322: . -snes_fas_cycles 1 or 2
324: Level: advanced
326: .seealso: SNESFASSetCyclesOnLevel()
327: @*/
328: PetscErrorCode SNESFASSetCycles(SNES snes, PetscInt cycles)
329: {
330: SNES_FAS *fas;
332: PetscBool isFine;
336: SNESFASCycleIsFine(snes, &isFine);
337: fas = (SNES_FAS*)snes->data;
338: fas->n_cycles = cycles;
339: if (!isFine) {
340: SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);
341: }
342: if (fas->next) {
343: SNESFASSetCycles(fas->next, cycles);
344: }
345: return(0);
346: }
348: /*@
349: SNESFASSetMonitor - Sets the method-specific cycle monitoring
351: Logically Collective on SNES
353: Input Parameters:
354: + snes - the FAS context
355: . vf - viewer and format structure (may be NULL if flg is FALSE)
356: - flg - monitor or not
358: Level: advanced
360: .seealso: SNESFASSetCyclesOnLevel()
361: @*/
362: PetscErrorCode SNESFASSetMonitor(SNES snes, PetscViewerAndFormat *vf, PetscBool flg)
363: {
364: SNES_FAS *fas;
366: PetscBool isFine;
367: PetscInt i, levels;
368: SNES levelsnes;
372: SNESFASCycleIsFine(snes, &isFine);
373: fas = (SNES_FAS*)snes->data;
374: levels = fas->levels;
375: if (isFine) {
376: for (i = 0; i < levels; i++) {
377: SNESFASGetCycleSNES(snes, i, &levelsnes);
378: fas = (SNES_FAS*)levelsnes->data;
379: if (flg) {
380: /* set the monitors for the upsmoother and downsmoother */
381: SNESMonitorCancel(levelsnes);
382: /* Only register destroy on finest level */
383: SNESMonitorSet(levelsnes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorDefault,vf,(!i ? (PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy : NULL));
384: } else if (i != fas->levels - 1) {
385: /* unset the monitors on the coarse levels */
386: SNESMonitorCancel(levelsnes);
387: }
388: }
389: }
390: return(0);
391: }
393: /*@
394: SNESFASSetLog - Sets or unsets time logging for various FAS stages on all levels
396: Logically Collective on SNES
398: Input Parameters:
399: + snes - the FAS context
400: - flg - monitor or not
402: Level: advanced
404: .seealso: SNESFASSetMonitor()
405: @*/
406: PetscErrorCode SNESFASSetLog(SNES snes, PetscBool flg)
407: {
408: SNES_FAS *fas;
410: PetscBool isFine;
411: PetscInt i, levels;
412: SNES levelsnes;
413: char eventname[128];
417: SNESFASCycleIsFine(snes, &isFine);
418: fas = (SNES_FAS*)snes->data;
419: levels = fas->levels;
420: if (isFine) {
421: for (i = 0; i < levels; i++) {
422: SNESFASGetCycleSNES(snes, i, &levelsnes);
423: fas = (SNES_FAS*)levelsnes->data;
424: if (flg) {
425: PetscSNPrintf(eventname,sizeof(eventname),"FASSetup %d",(int)i);
426: PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsetup);
427: PetscSNPrintf(eventname,sizeof(eventname),"FASSmooth %d",(int)i);
428: PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsolve);
429: PetscSNPrintf(eventname,sizeof(eventname),"FASResid %d",(int)i);
430: PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventresidual);
431: PetscSNPrintf(eventname,sizeof(eventname),"FASInterp %d",(int)i);
432: PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventinterprestrict);
433: } else {
434: fas->eventsmoothsetup = 0;
435: fas->eventsmoothsolve = 0;
436: fas->eventresidual = 0;
437: fas->eventinterprestrict = 0;
438: }
439: }
440: }
441: return(0);
442: }
444: /*
445: Creates the default smoother type.
447: This is SNESNRICHARDSON on each fine level and SNESNEWTONLS on the coarse level.
449: */
450: PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES snes, SNES *smooth)
451: {
452: SNES_FAS *fas;
453: const char *optionsprefix;
454: char tprefix[128];
456: SNES nsmooth;
461: fas = (SNES_FAS*)snes->data;
462: SNESGetOptionsPrefix(fas->fine, &optionsprefix);
463: /* create the default smoother */
464: SNESCreate(PetscObjectComm((PetscObject)snes), &nsmooth);
465: if (fas->level == 0) {
466: PetscStrncpy(tprefix,"fas_coarse_",sizeof(tprefix));
467: SNESAppendOptionsPrefix(nsmooth, optionsprefix);
468: SNESAppendOptionsPrefix(nsmooth, tprefix);
469: SNESSetType(nsmooth, SNESNEWTONLS);
470: SNESSetTolerances(nsmooth, nsmooth->abstol, nsmooth->rtol, nsmooth->stol, nsmooth->max_its, nsmooth->max_funcs);
471: } else {
472: PetscSNPrintf(tprefix,sizeof(tprefix),"fas_levels_%d_",(int)fas->level);
473: SNESAppendOptionsPrefix(nsmooth, optionsprefix);
474: SNESAppendOptionsPrefix(nsmooth, tprefix);
475: SNESSetType(nsmooth, SNESNRICHARDSON);
476: SNESSetTolerances(nsmooth, 0.0, 0.0, 0.0, fas->max_down_it, nsmooth->max_funcs);
477: }
478: PetscObjectIncrementTabLevel((PetscObject)nsmooth, (PetscObject)snes, 1);
479: PetscLogObjectParent((PetscObject)snes,(PetscObject)nsmooth);
480: PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)nsmooth);
481: PetscObjectComposedDataSetInt((PetscObject) nsmooth, PetscMGLevelId, fas->level);
482: *smooth = nsmooth;
483: return(0);
484: }
486: /* ------------- Functions called on a particular level ----------------- */
488: /*@
489: SNESFASCycleSetCycles - Sets the number of cycles on a particular level.
491: Logically Collective on SNES
493: Input Parameters:
494: + snes - the multigrid context
495: . level - the level to set the number of cycles on
496: - cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle
498: Level: advanced
500: .seealso: SNESFASSetCycles()
501: @*/
502: PetscErrorCode SNESFASCycleSetCycles(SNES snes, PetscInt cycles)
503: {
504: SNES_FAS *fas;
509: fas = (SNES_FAS*)snes->data;
510: fas->n_cycles = cycles;
511: SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);
512: return(0);
513: }
515: /*@
516: SNESFASCycleGetSmoother - Gets the smoother on a particular cycle level.
518: Logically Collective on SNES
520: Input Parameters:
521: . snes - the multigrid context
523: Output Parameters:
524: . smooth - the smoother
526: Level: advanced
528: .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmootherDown()
529: @*/
530: PetscErrorCode SNESFASCycleGetSmoother(SNES snes, SNES *smooth)
531: {
532: SNES_FAS *fas;
537: fas = (SNES_FAS*)snes->data;
538: *smooth = fas->smoothd;
539: return(0);
540: }
541: /*@
542: SNESFASCycleGetSmootherUp - Gets the up smoother on a particular cycle level.
544: Logically Collective on SNES
546: Input Parameters:
547: . snes - the multigrid context
549: Output Parameters:
550: . smoothu - the smoother
552: Notes:
553: Returns the downsmoother if no up smoother is available. This enables transparent
554: default behavior in the process of the solve.
556: Level: advanced
558: .seealso: SNESFASCycleGetSmoother(), SNESFASCycleGetSmootherDown()
559: @*/
560: PetscErrorCode SNESFASCycleGetSmootherUp(SNES snes, SNES *smoothu)
561: {
562: SNES_FAS *fas;
567: fas = (SNES_FAS*)snes->data;
568: if (!fas->smoothu) *smoothu = fas->smoothd;
569: else *smoothu = fas->smoothu;
570: return(0);
571: }
573: /*@
574: SNESFASCycleGetSmootherDown - Gets the down smoother on a particular cycle level.
576: Logically Collective on SNES
578: Input Parameters:
579: . snes - the multigrid context
581: Output Parameters:
582: . smoothd - the smoother
584: Level: advanced
586: .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
587: @*/
588: PetscErrorCode SNESFASCycleGetSmootherDown(SNES snes, SNES *smoothd)
589: {
590: SNES_FAS *fas;
595: fas = (SNES_FAS*)snes->data;
596: *smoothd = fas->smoothd;
597: return(0);
598: }
600: /*@
601: SNESFASCycleGetCorrection - Gets the coarse correction FAS context for this level
603: Logically Collective on SNES
605: Input Parameters:
606: . snes - the multigrid context
608: Output Parameters:
609: . correction - the coarse correction on this level
611: Notes:
612: Returns NULL on the coarsest level.
614: Level: advanced
616: .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
617: @*/
618: PetscErrorCode SNESFASCycleGetCorrection(SNES snes, SNES *correction)
619: {
620: SNES_FAS *fas;
625: fas = (SNES_FAS*)snes->data;
626: *correction = fas->next;
627: return(0);
628: }
630: /*@
631: SNESFASCycleGetInterpolation - Gets the interpolation on this level
633: Logically Collective on SNES
635: Input Parameters:
636: . snes - the multigrid context
638: Output Parameters:
639: . mat - the interpolation operator on this level
641: Level: developer
643: .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
644: @*/
645: PetscErrorCode SNESFASCycleGetInterpolation(SNES snes, Mat *mat)
646: {
647: SNES_FAS *fas;
652: fas = (SNES_FAS*)snes->data;
653: *mat = fas->interpolate;
654: return(0);
655: }
657: /*@
658: SNESFASCycleGetRestriction - Gets the restriction on this level
660: Logically Collective on SNES
662: Input Parameters:
663: . snes - the multigrid context
665: Output Parameters:
666: . mat - the restriction operator on this level
668: Level: developer
670: .seealso: SNESFASGetRestriction(), SNESFASCycleGetInterpolation()
671: @*/
672: PetscErrorCode SNESFASCycleGetRestriction(SNES snes, Mat *mat)
673: {
674: SNES_FAS *fas;
679: fas = (SNES_FAS*)snes->data;
680: *mat = fas->restrct;
681: return(0);
682: }
684: /*@
685: SNESFASCycleGetInjection - Gets the injection on this level
687: Logically Collective on SNES
689: Input Parameters:
690: . snes - the multigrid context
692: Output Parameters:
693: . mat - the restriction operator on this level
695: Level: developer
697: .seealso: SNESFASGetInjection(), SNESFASCycleGetRestriction()
698: @*/
699: PetscErrorCode SNESFASCycleGetInjection(SNES snes, Mat *mat)
700: {
701: SNES_FAS *fas;
706: fas = (SNES_FAS*)snes->data;
707: *mat = fas->inject;
708: return(0);
709: }
711: /*@
712: SNESFASCycleGetRScale - Gets the injection on this level
714: Logically Collective on SNES
716: Input Parameters:
717: . snes - the multigrid context
719: Output Parameters:
720: . mat - the restriction operator on this level
722: Level: developer
724: .seealso: SNESFASCycleGetRestriction(), SNESFASGetRScale()
725: @*/
726: PetscErrorCode SNESFASCycleGetRScale(SNES snes, Vec *vec)
727: {
728: SNES_FAS *fas;
733: fas = (SNES_FAS*)snes->data;
734: *vec = fas->rscale;
735: return(0);
736: }
738: /*@
739: SNESFASCycleIsFine - Determines if a given cycle is the fine level.
741: Logically Collective on SNES
743: Input Parameters:
744: . snes - the FAS context
746: Output Parameters:
747: . flg - indicates if this is the fine level or not
749: Level: advanced
751: .seealso: SNESFASSetLevels()
752: @*/
753: PetscErrorCode SNESFASCycleIsFine(SNES snes, PetscBool *flg)
754: {
755: SNES_FAS *fas;
760: fas = (SNES_FAS*)snes->data;
761: if (fas->level == fas->levels - 1) *flg = PETSC_TRUE;
762: else *flg = PETSC_FALSE;
763: return(0);
764: }
766: /* ---------- functions called on the finest level that return level-specific information ---------- */
768: /*@
769: SNESFASSetInterpolation - Sets the function to be used to calculate the
770: interpolation from l-1 to the lth level
772: Input Parameters:
773: + snes - the multigrid context
774: . mat - the interpolation operator
775: - level - the level (0 is coarsest) to supply [do not supply 0]
777: Level: advanced
779: Notes:
780: Usually this is the same matrix used also to set the restriction
781: for the same level.
783: One can pass in the interpolation matrix or its transpose; PETSc figures
784: out from the matrix size which one it is.
786: .seealso: SNESFASSetInjection(), SNESFASSetRestriction(), SNESFASSetRScale()
787: @*/
788: PetscErrorCode SNESFASSetInterpolation(SNES snes, PetscInt level, Mat mat)
789: {
790: SNES_FAS *fas;
792: SNES levelsnes;
797: SNESFASGetCycleSNES(snes, level, &levelsnes);
798: fas = (SNES_FAS*)levelsnes->data;
799: PetscObjectReference((PetscObject)mat);
800: MatDestroy(&fas->interpolate);
801: fas->interpolate = mat;
802: return(0);
803: }
805: /*@
806: SNESFASGetInterpolation - Gets the matrix used to calculate the
807: interpolation from l-1 to the lth level
809: Input Parameters:
810: + snes - the multigrid context
811: - level - the level (0 is coarsest) to supply [do not supply 0]
813: Output Parameters:
814: . mat - the interpolation operator
816: Level: advanced
818: .seealso: SNESFASSetInterpolation(), SNESFASGetInjection(), SNESFASGetRestriction(), SNESFASGetRScale()
819: @*/
820: PetscErrorCode SNESFASGetInterpolation(SNES snes, PetscInt level, Mat *mat)
821: {
822: SNES_FAS *fas;
824: SNES levelsnes;
829: SNESFASGetCycleSNES(snes, level, &levelsnes);
830: fas = (SNES_FAS*)levelsnes->data;
831: *mat = fas->interpolate;
832: return(0);
833: }
835: /*@
836: SNESFASSetRestriction - Sets the function to be used to restrict the defect
837: from level l to l-1.
839: Input Parameters:
840: + snes - the multigrid context
841: . mat - the restriction matrix
842: - level - the level (0 is coarsest) to supply [Do not supply 0]
844: Level: advanced
846: Notes:
847: Usually this is the same matrix used also to set the interpolation
848: for the same level.
850: One can pass in the interpolation matrix or its transpose; PETSc figures
851: out from the matrix size which one it is.
853: If you do not set this, the transpose of the Mat set with SNESFASSetInterpolation()
854: is used.
856: .seealso: SNESFASSetInterpolation(), SNESFASSetInjection()
857: @*/
858: PetscErrorCode SNESFASSetRestriction(SNES snes, PetscInt level, Mat mat)
859: {
860: SNES_FAS *fas;
862: SNES levelsnes;
867: SNESFASGetCycleSNES(snes, level, &levelsnes);
868: fas = (SNES_FAS*)levelsnes->data;
869: PetscObjectReference((PetscObject)mat);
870: MatDestroy(&fas->restrct);
871: fas->restrct = mat;
872: return(0);
873: }
875: /*@
876: SNESFASGetRestriction - Gets the matrix used to calculate the
877: restriction from l to the l-1th level
879: Input Parameters:
880: + snes - the multigrid context
881: - level - the level (0 is coarsest) to supply [do not supply 0]
883: Output Parameters:
884: . mat - the interpolation operator
886: Level: advanced
888: .seealso: SNESFASSetRestriction(), SNESFASGetInjection(), SNESFASGetInterpolation(), SNESFASGetRScale()
889: @*/
890: PetscErrorCode SNESFASGetRestriction(SNES snes, PetscInt level, Mat *mat)
891: {
892: SNES_FAS *fas;
894: SNES levelsnes;
899: SNESFASGetCycleSNES(snes, level, &levelsnes);
900: fas = (SNES_FAS*)levelsnes->data;
901: *mat = fas->restrct;
902: return(0);
903: }
905: /*@
906: SNESFASSetInjection - Sets the function to be used to inject the solution
907: from level l to l-1.
909: Input Parameters:
910: + snes - the multigrid context
911: . mat - the restriction matrix
912: - level - the level (0 is coarsest) to supply [Do not supply 0]
914: Level: advanced
916: Notes:
917: If you do not set this, the restriction and rscale is used to
918: project the solution instead.
920: .seealso: SNESFASSetInterpolation(), SNESFASSetRestriction()
921: @*/
922: PetscErrorCode SNESFASSetInjection(SNES snes, PetscInt level, Mat mat)
923: {
924: SNES_FAS *fas;
926: SNES levelsnes;
931: SNESFASGetCycleSNES(snes, level, &levelsnes);
932: fas = (SNES_FAS*)levelsnes->data;
933: PetscObjectReference((PetscObject)mat);
934: MatDestroy(&fas->inject);
936: fas->inject = mat;
937: return(0);
938: }
940: /*@
941: SNESFASGetInjection - Gets the matrix used to calculate the
942: injection from l-1 to the lth level
944: Input Parameters:
945: + snes - the multigrid context
946: - level - the level (0 is coarsest) to supply [do not supply 0]
948: Output Parameters:
949: . mat - the injection operator
951: Level: advanced
953: .seealso: SNESFASSetInjection(), SNESFASGetRestriction(), SNESFASGetInterpolation(), SNESFASGetRScale()
954: @*/
955: PetscErrorCode SNESFASGetInjection(SNES snes, PetscInt level, Mat *mat)
956: {
957: SNES_FAS *fas;
959: SNES levelsnes;
964: SNESFASGetCycleSNES(snes, level, &levelsnes);
965: fas = (SNES_FAS*)levelsnes->data;
966: *mat = fas->inject;
967: return(0);
968: }
970: /*@
971: SNESFASSetRScale - Sets the scaling factor of the restriction
972: operator from level l to l-1.
974: Input Parameters:
975: + snes - the multigrid context
976: . rscale - the restriction scaling
977: - level - the level (0 is coarsest) to supply [Do not supply 0]
979: Level: advanced
981: Notes:
982: This is only used in the case that the injection is not set.
984: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
985: @*/
986: PetscErrorCode SNESFASSetRScale(SNES snes, PetscInt level, Vec rscale)
987: {
988: SNES_FAS *fas;
990: SNES levelsnes;
995: SNESFASGetCycleSNES(snes, level, &levelsnes);
996: fas = (SNES_FAS*)levelsnes->data;
997: PetscObjectReference((PetscObject)rscale);
998: VecDestroy(&fas->rscale);
999: fas->rscale = rscale;
1000: return(0);
1001: }
1003: /*@
1004: SNESFASGetSmoother - Gets the default smoother on a level.
1006: Input Parameters:
1007: + snes - the multigrid context
1008: - level - the level (0 is coarsest) to supply
1010: Output Parameters:
1011: smooth - the smoother
1013: Level: advanced
1015: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1016: @*/
1017: PetscErrorCode SNESFASGetSmoother(SNES snes, PetscInt level, SNES *smooth)
1018: {
1019: SNES_FAS *fas;
1021: SNES levelsnes;
1026: SNESFASGetCycleSNES(snes, level, &levelsnes);
1027: fas = (SNES_FAS*)levelsnes->data;
1028: if (!fas->smoothd) {
1029: SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);
1030: }
1031: *smooth = fas->smoothd;
1032: return(0);
1033: }
1035: /*@
1036: SNESFASGetSmootherDown - Gets the downsmoother on a level.
1038: Input Parameters:
1039: + snes - the multigrid context
1040: - level - the level (0 is coarsest) to supply
1042: Output Parameters:
1043: smooth - the smoother
1045: Level: advanced
1047: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1048: @*/
1049: PetscErrorCode SNESFASGetSmootherDown(SNES snes, PetscInt level, SNES *smooth)
1050: {
1051: SNES_FAS *fas;
1053: SNES levelsnes;
1058: SNESFASGetCycleSNES(snes, level, &levelsnes);
1059: fas = (SNES_FAS*)levelsnes->data;
1060: /* if the user chooses to differentiate smoothers, create them both at this point */
1061: if (!fas->smoothd) {
1062: SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);
1063: }
1064: if (!fas->smoothu) {
1065: SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);
1066: }
1067: *smooth = fas->smoothd;
1068: return(0);
1069: }
1071: /*@
1072: SNESFASGetSmootherUp - Gets the upsmoother on a level.
1074: Input Parameters:
1075: + snes - the multigrid context
1076: - level - the level (0 is coarsest)
1078: Output Parameters:
1079: smooth - the smoother
1081: Level: advanced
1083: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1084: @*/
1085: PetscErrorCode SNESFASGetSmootherUp(SNES snes, PetscInt level, SNES *smooth)
1086: {
1087: SNES_FAS *fas;
1089: SNES levelsnes;
1094: SNESFASGetCycleSNES(snes, level, &levelsnes);
1095: fas = (SNES_FAS*)levelsnes->data;
1096: /* if the user chooses to differentiate smoothers, create them both at this point */
1097: if (!fas->smoothd) {
1098: SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);
1099: }
1100: if (!fas->smoothu) {
1101: SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);
1102: }
1103: *smooth = fas->smoothu;
1104: return(0);
1105: }
1107: /*@
1108: SNESFASGetCoarseSolve - Gets the coarsest solver.
1110: Input Parameters:
1111: . snes - the multigrid context
1113: Output Parameters:
1114: . coarse - the coarse-level solver
1116: Level: advanced
1118: .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1119: @*/
1120: PetscErrorCode SNESFASGetCoarseSolve(SNES snes, SNES *coarse)
1121: {
1122: SNES_FAS *fas;
1124: SNES levelsnes;
1129: SNESFASGetCycleSNES(snes, 0, &levelsnes);
1130: fas = (SNES_FAS*)levelsnes->data;
1131: /* if the user chooses to differentiate smoothers, create them both at this point */
1132: if (!fas->smoothd) {
1133: SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);
1134: }
1135: *coarse = fas->smoothd;
1136: return(0);
1137: }
1139: /*@
1140: SNESFASFullSetDownSweep - Smooth during the initial downsweep for SNESFAS
1142: Logically Collective on SNES
1144: Input Parameters:
1145: + snes - the multigrid context
1146: - swp - whether to downsweep or not
1148: Options Database Key:
1149: . -snes_fas_full_downsweep - Sets number of pre-smoothing steps
1151: Level: advanced
1153: .seealso: SNESFASSetNumberSmoothUp()
1154: @*/
1155: PetscErrorCode SNESFASFullSetDownSweep(SNES snes,PetscBool swp)
1156: {
1157: SNES_FAS *fas;
1162: fas = (SNES_FAS*)snes->data;
1163: fas->full_downsweep = swp;
1164: if (fas->next) {
1165: SNESFASFullSetDownSweep(fas->next,swp);
1166: }
1167: return(0);
1168: }
1170: /*@
1171: SNESFASFullSetTotal - Use total residual restriction and total interpolation on the initial down and up sweep of full FAS cycles
1173: Logically Collective on SNES
1175: Input Parameters:
1176: + snes - the multigrid context
1177: - total - whether to use total restriction / interpolatiaon or not (the alternative is defect restriction and correction interpolation)
1179: Options Database Key:
1180: . -snes_fas_full_total
1182: Level: advanced
1184: Note: this option is only significant if the interpolation of a coarse correction (MatInterpolate()) is significantly different from total solution interpolation (DMInterpolateSolution()).
1186: .seealso: SNESFASSetNumberSmoothUp(), DMInterpolateSolution()
1187: @*/
1188: PetscErrorCode SNESFASFullSetTotal(SNES snes,PetscBool total)
1189: {
1190: SNES_FAS *fas;
1195: fas = (SNES_FAS*)snes->data;
1196: fas->full_total = total;
1197: if (fas->next) {
1198: SNESFASFullSetTotal(fas->next,total);
1199: }
1200: return(0);
1201: }
1203: /*@
1204: SNESFASFullGetTotal - Use total residual restriction and total interpolation on the initial down and up sweep of full FAS cycles
1206: Logically Collective on SNES
1208: Input Parameters:
1209: . snes - the multigrid context
1211: Output:
1212: . total - whether to use total restriction / interpolatiaon or not (the alternative is defect restriction and correction interpolation)
1214: Options Database Key:
1215: . -snes_fas_full_total
1217: Level: advanced
1219: .seealso: SNESFASSetNumberSmoothUp(), DMInterpolateSolution(), SNESFullSetTotal()
1220: @*/
1221: PetscErrorCode SNESFASFullGetTotal(SNES snes,PetscBool *total)
1222: {
1223: SNES_FAS *fas;
1227: fas = (SNES_FAS*)snes->data;
1228: *total = fas->full_total;
1229: return(0);
1230: }