xref: /petsc/src/snes/impls/fas/fasfunc.c (revision 95452b02e12c0ee11232c7ff2b24b568a8e07e43)
1a7b5fb5fSBarry Smith #include <../src/snes/impls/fas/fasimpls.h> /*I  "petscsnes.h"  I*/
2ab8d36c9SPeter Brune 
3ab8d36c9SPeter Brune 
4ab8d36c9SPeter Brune /* -------------- functions called on the fine level -------------- */
5ab8d36c9SPeter Brune 
6ab8d36c9SPeter Brune /*@
7ab8d36c9SPeter Brune     SNESFASSetType - Sets the update and correction type used for FAS.
8ab8d36c9SPeter Brune 
9ab8d36c9SPeter Brune    Logically Collective
10ab8d36c9SPeter Brune 
11ab8d36c9SPeter Brune Input Parameters:
12583a1250SSatish Balay + snes  - FAS context
1334d65b3cSPeter Brune - fastype  - SNES_FAS_ADDITIVE, SNES_FAS_MULTIPLICATIVE, SNES_FAS_FULL, or SNES_FAS_KASKADE
14583a1250SSatish Balay 
15583a1250SSatish Balay Level: intermediate
16ab8d36c9SPeter Brune 
17ab8d36c9SPeter Brune .seealso: PCMGSetType()
18ab8d36c9SPeter Brune @*/
19ab8d36c9SPeter Brune PetscErrorCode  SNESFASSetType(SNES snes,SNESFASType fastype)
20ab8d36c9SPeter Brune {
21ab8d36c9SPeter Brune   SNES_FAS       *fas = (SNES_FAS*)snes->data;
22ab8d36c9SPeter Brune   PetscErrorCode ierr;
2322d28d08SBarry Smith 
24ab8d36c9SPeter Brune   PetscFunctionBegin;
25ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
26ab8d36c9SPeter Brune   PetscValidLogicalCollectiveEnum(snes,fastype,2);
27ab8d36c9SPeter Brune   fas->fastype = fastype;
2822d28d08SBarry Smith   if (fas->next) {
2922d28d08SBarry Smith     ierr = SNESFASSetType(fas->next, fastype);CHKERRQ(ierr);
3022d28d08SBarry Smith   }
31ab8d36c9SPeter Brune   PetscFunctionReturn(0);
32ab8d36c9SPeter Brune }
33ab8d36c9SPeter Brune 
34ab8d36c9SPeter Brune 
35ab8d36c9SPeter Brune /*@
36ab8d36c9SPeter Brune SNESFASGetType - Sets the update and correction type used for FAS.
37ab8d36c9SPeter Brune 
38ab8d36c9SPeter Brune Logically Collective
39ab8d36c9SPeter Brune 
40ab8d36c9SPeter Brune Input Parameters:
41ab8d36c9SPeter Brune . snes - FAS context
42ab8d36c9SPeter Brune 
43ab8d36c9SPeter Brune Output Parameters:
44ab8d36c9SPeter Brune . fastype - SNES_FAS_ADDITIVE or SNES_FAS_MULTIPLICATIVE
45ab8d36c9SPeter Brune 
46583a1250SSatish Balay Level: intermediate
47583a1250SSatish Balay 
48ab8d36c9SPeter Brune .seealso: PCMGSetType()
49ab8d36c9SPeter Brune @*/
50ab8d36c9SPeter Brune PetscErrorCode  SNESFASGetType(SNES snes,SNESFASType *fastype)
51ab8d36c9SPeter Brune {
52ab8d36c9SPeter Brune   SNES_FAS *fas = (SNES_FAS*)snes->data;
53ab8d36c9SPeter Brune 
54ab8d36c9SPeter Brune   PetscFunctionBegin;
55ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
56ab8d36c9SPeter Brune   PetscValidPointer(fastype, 2);
57ab8d36c9SPeter Brune   *fastype = fas->fastype;
58ab8d36c9SPeter Brune   PetscFunctionReturn(0);
59ab8d36c9SPeter Brune }
60ab8d36c9SPeter Brune 
61ab8d36c9SPeter Brune /*@C
62ab8d36c9SPeter Brune    SNESFASSetLevels - Sets the number of levels to use with FAS.
63ab8d36c9SPeter Brune    Must be called before any other FAS routine.
64ab8d36c9SPeter Brune 
65ab8d36c9SPeter Brune    Input Parameters:
66ab8d36c9SPeter Brune +  snes   - the snes context
67ab8d36c9SPeter Brune .  levels - the number of levels
68ab8d36c9SPeter Brune -  comms  - optional communicators for each level; this is to allow solving the coarser
692bf68e3eSBarry Smith             problems on smaller sets of processors.
70ab8d36c9SPeter Brune 
71ab8d36c9SPeter Brune    Level: intermediate
72ab8d36c9SPeter Brune 
73ab8d36c9SPeter Brune    Notes:
74ab8d36c9SPeter Brune      If the number of levels is one then the multigrid uses the -fas_levels prefix
75ab8d36c9SPeter Brune   for setting the level options rather than the -fas_coarse prefix.
76ab8d36c9SPeter Brune 
77ab8d36c9SPeter Brune .keywords: FAS, MG, set, levels, multigrid
78ab8d36c9SPeter Brune 
79ab8d36c9SPeter Brune .seealso: SNESFASGetLevels()
80ab8d36c9SPeter Brune @*/
8122d28d08SBarry Smith PetscErrorCode SNESFASSetLevels(SNES snes, PetscInt levels, MPI_Comm * comms)
8222d28d08SBarry Smith {
83ab8d36c9SPeter Brune   PetscErrorCode ierr;
84ab8d36c9SPeter Brune   PetscInt       i;
85ab8d36c9SPeter Brune   const char     *optionsprefix;
86ab8d36c9SPeter Brune   char           tprefix[128];
87ab8d36c9SPeter Brune   SNES_FAS       *fas = (SNES_FAS*)snes->data;
88ab8d36c9SPeter Brune   SNES           prevsnes;
89ab8d36c9SPeter Brune   MPI_Comm       comm;
9022d28d08SBarry Smith 
91ab8d36c9SPeter Brune   PetscFunctionBegin;
92ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
93ab8d36c9SPeter Brune   if (levels == fas->levels) {
9422d28d08SBarry Smith     if (!comms) PetscFunctionReturn(0);
95ab8d36c9SPeter Brune   }
96ab8d36c9SPeter Brune   /* user has changed the number of levels; reset */
97ab8d36c9SPeter Brune   ierr = SNESReset(snes);CHKERRQ(ierr);
98ab8d36c9SPeter Brune   /* destroy any coarser levels if necessary */
99ab8d36c9SPeter Brune   if (fas->next) SNESDestroy(&fas->next);CHKERRQ(ierr);
1000298fd71SBarry Smith   fas->next     = NULL;
1010298fd71SBarry Smith   fas->previous = NULL;
102ab8d36c9SPeter Brune   prevsnes      = snes;
103ab8d36c9SPeter Brune   /* setup the finest level */
104ab8d36c9SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
105ab83eea4SMatthew G. Knepley   ierr = PetscObjectComposedDataSetInt((PetscObject) snes, PetscMGLevelId, levels-1);CHKERRQ(ierr);
106ab8d36c9SPeter Brune   for (i = levels - 1; i >= 0; i--) {
107ab8d36c9SPeter Brune     if (comms) comm = comms[i];
108ab8d36c9SPeter Brune     fas->level  = i;
109ab8d36c9SPeter Brune     fas->levels = levels;
110ab8d36c9SPeter Brune     fas->fine   = snes;
1110298fd71SBarry Smith     fas->next   = NULL;
112ab8d36c9SPeter Brune     if (i > 0) {
113ab8d36c9SPeter Brune       ierr = SNESCreate(comm, &fas->next);CHKERRQ(ierr);
114e964f0dbSPeter Brune       ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr);
115ab8d36c9SPeter Brune       sprintf(tprefix,"fas_levels_%d_cycle_",(int)fas->level);
116ab8d36c9SPeter Brune       ierr = SNESAppendOptionsPrefix(fas->next,optionsprefix);CHKERRQ(ierr);
117e964f0dbSPeter Brune       ierr = SNESAppendOptionsPrefix(fas->next,tprefix);CHKERRQ(ierr);
118ab8d36c9SPeter Brune       ierr = SNESSetType(fas->next, SNESFAS);CHKERRQ(ierr);
119ab8d36c9SPeter Brune       ierr = SNESSetTolerances(fas->next, fas->next->abstol, fas->next->rtol, fas->next->stol, fas->n_cycles, fas->next->max_funcs);CHKERRQ(ierr);
120ab8d36c9SPeter Brune       ierr = PetscObjectIncrementTabLevel((PetscObject)fas->next, (PetscObject)snes, levels - i);CHKERRQ(ierr);
121ab83eea4SMatthew G. Knepley       ierr = PetscObjectComposedDataSetInt((PetscObject) fas->next, PetscMGLevelId, i-1);CHKERRQ(ierr);
1221aa26658SKarl Rupp 
123ab8d36c9SPeter Brune       ((SNES_FAS*)fas->next->data)->previous = prevsnes;
1241aa26658SKarl Rupp 
125ab8d36c9SPeter Brune       prevsnes = fas->next;
126ab8d36c9SPeter Brune       fas      = (SNES_FAS*)prevsnes->data;
127ab8d36c9SPeter Brune     }
128ab8d36c9SPeter Brune   }
129ab8d36c9SPeter Brune   PetscFunctionReturn(0);
130ab8d36c9SPeter Brune }
131ab8d36c9SPeter Brune 
132ab8d36c9SPeter Brune 
133ab8d36c9SPeter Brune /*@
134ab8d36c9SPeter Brune    SNESFASGetLevels - Gets the number of levels in a FAS, including fine and coarse grids
135ab8d36c9SPeter Brune 
136ab8d36c9SPeter Brune    Input Parameter:
137ab8d36c9SPeter Brune .  snes - the nonlinear solver context
138ab8d36c9SPeter Brune 
139ab8d36c9SPeter Brune    Output parameter:
140ab8d36c9SPeter Brune .  levels - the number of levels
141ab8d36c9SPeter Brune 
142ab8d36c9SPeter Brune    Level: advanced
143ab8d36c9SPeter Brune 
144ab8d36c9SPeter Brune .keywords: MG, get, levels, multigrid
145ab8d36c9SPeter Brune 
146ab8d36c9SPeter Brune .seealso: SNESFASSetLevels(), PCMGGetLevels()
147ab8d36c9SPeter Brune @*/
14822d28d08SBarry Smith PetscErrorCode SNESFASGetLevels(SNES snes, PetscInt *levels)
14922d28d08SBarry Smith {
150ab8d36c9SPeter Brune   SNES_FAS * fas = (SNES_FAS*)snes->data;
1515fd66863SKarl Rupp 
152ab8d36c9SPeter Brune   PetscFunctionBegin;
153ab8d36c9SPeter Brune   *levels = fas->levels;
154ab8d36c9SPeter Brune   PetscFunctionReturn(0);
155ab8d36c9SPeter Brune }
156ab8d36c9SPeter Brune 
157ab8d36c9SPeter Brune 
158ab8d36c9SPeter Brune /*@
159ab8d36c9SPeter Brune    SNESFASGetCycleSNES - Gets the SNES corresponding to a particular
160ab8d36c9SPeter Brune    level of the FAS hierarchy.
161ab8d36c9SPeter Brune 
162ab8d36c9SPeter Brune    Input Parameters:
163ab8d36c9SPeter Brune +  snes    - the multigrid context
164ab8d36c9SPeter Brune    level   - the level to get
165ab8d36c9SPeter Brune -  lsnes   - whether to use the nonlinear smoother or not
166ab8d36c9SPeter Brune 
167ab8d36c9SPeter Brune    Level: advanced
168ab8d36c9SPeter Brune 
169ab8d36c9SPeter Brune .keywords: FAS, MG, set, cycles, Gauss-Seidel, multigrid
170ab8d36c9SPeter Brune 
171ab8d36c9SPeter Brune .seealso: SNESFASSetLevels(), SNESFASGetLevels()
172ab8d36c9SPeter Brune @*/
17322d28d08SBarry Smith PetscErrorCode SNESFASGetCycleSNES(SNES snes,PetscInt level,SNES *lsnes)
17422d28d08SBarry Smith {
175ab8d36c9SPeter Brune   SNES_FAS *fas = (SNES_FAS*)snes->data;
176ab8d36c9SPeter Brune   PetscInt i;
177ab8d36c9SPeter Brune 
178ab8d36c9SPeter Brune   PetscFunctionBegin;
179ce94432eSBarry Smith   if (level > fas->levels-1) SETERRQ2(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Requested level %D from SNESFAS containing %D levels",level,fas->levels);
180ce94432eSBarry Smith   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);
181ab8d36c9SPeter Brune 
182ab8d36c9SPeter Brune   *lsnes = snes;
183ab8d36c9SPeter Brune   for (i = fas->level; i > level; i--) {
184ab8d36c9SPeter Brune     *lsnes = fas->next;
185ab8d36c9SPeter Brune     fas    = (SNES_FAS*)(*lsnes)->data;
186ab8d36c9SPeter Brune   }
187ce94432eSBarry Smith   if (fas->level != level) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"SNESFAS level hierarchy corrupt");
188ab8d36c9SPeter Brune   PetscFunctionReturn(0);
189ab8d36c9SPeter Brune }
190ab8d36c9SPeter Brune 
191ab8d36c9SPeter Brune /*@
192ab8d36c9SPeter Brune    SNESFASSetNumberSmoothUp - Sets the number of post-smoothing steps to
193ab8d36c9SPeter Brune    use on all levels.
194ab8d36c9SPeter Brune 
195ab8d36c9SPeter Brune    Logically Collective on SNES
196ab8d36c9SPeter Brune 
197ab8d36c9SPeter Brune    Input Parameters:
198ab8d36c9SPeter Brune +  snes - the multigrid context
199ab8d36c9SPeter Brune -  n    - the number of smoothing steps
200ab8d36c9SPeter Brune 
201ab8d36c9SPeter Brune    Options Database Key:
202ab8d36c9SPeter Brune .  -snes_fas_smoothup <n> - Sets number of pre-smoothing steps
203ab8d36c9SPeter Brune 
204ab8d36c9SPeter Brune    Level: advanced
205ab8d36c9SPeter Brune 
206ab8d36c9SPeter Brune .keywords: FAS, MG, smooth, down, pre-smoothing, steps, multigrid
207ab8d36c9SPeter Brune 
208ab8d36c9SPeter Brune .seealso: SNESFASSetNumberSmoothDown()
209ab8d36c9SPeter Brune @*/
21022d28d08SBarry Smith PetscErrorCode SNESFASSetNumberSmoothUp(SNES snes, PetscInt n)
21122d28d08SBarry Smith {
212ab8d36c9SPeter Brune   SNES_FAS       *fas =  (SNES_FAS*)snes->data;
21322d28d08SBarry Smith   PetscErrorCode ierr;
21422d28d08SBarry Smith 
215ab8d36c9SPeter Brune   PetscFunctionBegin;
216ab8d36c9SPeter Brune   fas->max_up_it = n;
217656ede7eSPeter Brune   if (!fas->smoothu && fas->level != 0) {
21822d28d08SBarry Smith     ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);CHKERRQ(ierr);
219ab8d36c9SPeter Brune   }
22022d28d08SBarry Smith   if (fas->smoothu) {
22122d28d08SBarry Smith     ierr = SNESSetTolerances(fas->smoothu, fas->smoothu->abstol, fas->smoothu->rtol, fas->smoothu->stol, n, fas->smoothu->max_funcs);CHKERRQ(ierr);
22222d28d08SBarry Smith   }
223ab8d36c9SPeter Brune   if (fas->next) {
224ab8d36c9SPeter Brune     ierr = SNESFASSetNumberSmoothUp(fas->next, n);CHKERRQ(ierr);
225ab8d36c9SPeter Brune   }
226ab8d36c9SPeter Brune   PetscFunctionReturn(0);
227ab8d36c9SPeter Brune }
228ab8d36c9SPeter Brune 
229ab8d36c9SPeter Brune /*@
230ab8d36c9SPeter Brune    SNESFASSetNumberSmoothDown - Sets the number of pre-smoothing steps to
231ab8d36c9SPeter Brune    use on all levels.
232ab8d36c9SPeter Brune 
233ab8d36c9SPeter Brune    Logically Collective on SNES
234ab8d36c9SPeter Brune 
235ab8d36c9SPeter Brune    Input Parameters:
236ab8d36c9SPeter Brune +  snes - the multigrid context
237ab8d36c9SPeter Brune -  n    - the number of smoothing steps
238ab8d36c9SPeter Brune 
239ab8d36c9SPeter Brune    Options Database Key:
240ab8d36c9SPeter Brune .  -snes_fas_smoothdown <n> - Sets number of pre-smoothing steps
241ab8d36c9SPeter Brune 
242ab8d36c9SPeter Brune    Level: advanced
243ab8d36c9SPeter Brune 
244ab8d36c9SPeter Brune .keywords: FAS, MG, smooth, down, pre-smoothing, steps, multigrid
245ab8d36c9SPeter Brune 
246ab8d36c9SPeter Brune .seealso: SNESFASSetNumberSmoothUp()
247ab8d36c9SPeter Brune @*/
24822d28d08SBarry Smith PetscErrorCode SNESFASSetNumberSmoothDown(SNES snes, PetscInt n)
24922d28d08SBarry Smith {
250ab8d36c9SPeter Brune   SNES_FAS       *fas =  (SNES_FAS*)snes->data;
251ab8d36c9SPeter Brune   PetscErrorCode ierr = 0;
25222d28d08SBarry Smith 
253ab8d36c9SPeter Brune   PetscFunctionBegin;
254ab8d36c9SPeter Brune   if (!fas->smoothd) {
25522d28d08SBarry Smith     ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);CHKERRQ(ierr);
256ab8d36c9SPeter Brune   }
257ab8d36c9SPeter Brune   ierr = SNESSetTolerances(fas->smoothd, fas->smoothd->abstol, fas->smoothd->rtol, fas->smoothd->stol, n, fas->smoothd->max_funcs);CHKERRQ(ierr);
2581aa26658SKarl Rupp 
259ab8d36c9SPeter Brune   fas->max_down_it = n;
260ab8d36c9SPeter Brune   if (fas->next) {
261ab8d36c9SPeter Brune     ierr = SNESFASSetNumberSmoothDown(fas->next, n);CHKERRQ(ierr);
262ab8d36c9SPeter Brune   }
263ab8d36c9SPeter Brune   PetscFunctionReturn(0);
264ab8d36c9SPeter Brune }
265ab8d36c9SPeter Brune 
266ab8d36c9SPeter Brune 
26787f44e3fSPeter Brune /*@
26887f44e3fSPeter Brune    SNESFASSetContinuation - Sets the FAS cycle to default to exact Newton solves on the upsweep
26987f44e3fSPeter Brune 
27087f44e3fSPeter Brune    Logically Collective on SNES
27187f44e3fSPeter Brune 
27287f44e3fSPeter Brune    Input Parameters:
27387f44e3fSPeter Brune +  snes - the multigrid context
27487f44e3fSPeter Brune -  n    - the number of smoothing steps
27587f44e3fSPeter Brune 
27687f44e3fSPeter Brune    Options Database Key:
27787f44e3fSPeter Brune .  -snes_fas_continuation - sets continuation to true
27887f44e3fSPeter Brune 
27987f44e3fSPeter Brune    Level: advanced
28087f44e3fSPeter Brune 
281*95452b02SPatrick Sanan    Notes:
282*95452b02SPatrick Sanan     This sets the prefix on the upsweep smoothers to -fas_continuation
28387f44e3fSPeter Brune 
28487f44e3fSPeter Brune .keywords: FAS, MG, smoother, continuation
28587f44e3fSPeter Brune 
28687f44e3fSPeter Brune .seealso: SNESFAS
28787f44e3fSPeter Brune @*/
28887f44e3fSPeter Brune PetscErrorCode SNESFASSetContinuation(SNES snes,PetscBool continuation)
28987f44e3fSPeter Brune {
29087f44e3fSPeter Brune   const char     *optionsprefix;
29187f44e3fSPeter Brune   char           tprefix[128];
29287f44e3fSPeter Brune   SNES_FAS       *fas =  (SNES_FAS*)snes->data;
29387f44e3fSPeter Brune   PetscErrorCode ierr = 0;
29487f44e3fSPeter Brune 
29587f44e3fSPeter Brune   PetscFunctionBegin;
29687f44e3fSPeter Brune   ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr);
29787f44e3fSPeter Brune   if (!fas->smoothu) {
29887f44e3fSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);CHKERRQ(ierr);
29987f44e3fSPeter Brune   }
30087f44e3fSPeter Brune   sprintf(tprefix,"fas_levels_continuation_");
30187f44e3fSPeter Brune   ierr = SNESSetOptionsPrefix(fas->smoothu, optionsprefix);CHKERRQ(ierr);
30287f44e3fSPeter Brune   ierr = SNESAppendOptionsPrefix(fas->smoothu, tprefix);CHKERRQ(ierr);
30387f44e3fSPeter Brune   ierr = SNESSetType(fas->smoothu,SNESNEWTONLS);CHKERRQ(ierr);
30487f44e3fSPeter Brune   ierr = SNESSetTolerances(fas->smoothu,fas->fine->abstol,fas->fine->rtol,fas->fine->stol,50,100);CHKERRQ(ierr);
30587f44e3fSPeter Brune   fas->continuation = continuation;
30687f44e3fSPeter Brune   if (fas->next) {
30787f44e3fSPeter Brune     ierr = SNESFASSetContinuation(fas->next,continuation);CHKERRQ(ierr);
30887f44e3fSPeter Brune   }
30987f44e3fSPeter Brune   PetscFunctionReturn(0);
31087f44e3fSPeter Brune }
31187f44e3fSPeter Brune 
31287f44e3fSPeter Brune 
313ab8d36c9SPeter Brune /*@
314ab8d36c9SPeter Brune    SNESFASSetCycles - Sets the number of FAS multigrid cycles to use each time a grid is visited.  Use SNESFASSetCyclesOnLevel() for more
315ab8d36c9SPeter Brune    complicated cycling.
316ab8d36c9SPeter Brune 
317ab8d36c9SPeter Brune    Logically Collective on SNES
318ab8d36c9SPeter Brune 
319ab8d36c9SPeter Brune    Input Parameters:
320ab8d36c9SPeter Brune +  snes   - the multigrid context
321ab8d36c9SPeter Brune -  cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle
322ab8d36c9SPeter Brune 
323ab8d36c9SPeter Brune    Options Database Key:
324e1bc860dSBarry Smith .  -snes_fas_cycles 1 or 2
325ab8d36c9SPeter Brune 
326ab8d36c9SPeter Brune    Level: advanced
327ab8d36c9SPeter Brune 
328ab8d36c9SPeter Brune .keywords: MG, set, cycles, V-cycle, W-cycle, multigrid
329ab8d36c9SPeter Brune 
330ab8d36c9SPeter Brune .seealso: SNESFASSetCyclesOnLevel()
331ab8d36c9SPeter Brune @*/
33222d28d08SBarry Smith PetscErrorCode SNESFASSetCycles(SNES snes, PetscInt cycles)
33322d28d08SBarry Smith {
334ab8d36c9SPeter Brune   SNES_FAS       *fas = (SNES_FAS*)snes->data;
335ab8d36c9SPeter Brune   PetscErrorCode ierr;
336ab8d36c9SPeter Brune   PetscBool      isFine;
33722d28d08SBarry Smith 
338ab8d36c9SPeter Brune   PetscFunctionBegin;
33922d28d08SBarry Smith   ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr);
3401aa26658SKarl Rupp 
341ab8d36c9SPeter Brune   fas->n_cycles = cycles;
3421aa26658SKarl Rupp   if (!isFine) {
343ab8d36c9SPeter Brune     ierr = SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);CHKERRQ(ierr);
3441aa26658SKarl Rupp   }
345ab8d36c9SPeter Brune   if (fas->next) {
346ab8d36c9SPeter Brune     ierr = SNESFASSetCycles(fas->next, cycles);CHKERRQ(ierr);
347ab8d36c9SPeter Brune   }
348ab8d36c9SPeter Brune   PetscFunctionReturn(0);
349ab8d36c9SPeter Brune }
350ab8d36c9SPeter Brune 
351c8c899caSPeter Brune 
352c8c899caSPeter Brune /*@
353c8c899caSPeter Brune    SNESFASSetMonitor - Sets the method-specific cycle monitoring
354c8c899caSPeter Brune 
355c8c899caSPeter Brune    Logically Collective on SNES
356c8c899caSPeter Brune 
357c8c899caSPeter Brune    Input Parameters:
358c8c899caSPeter Brune +  snes   - the FAS context
359d142ab34SLawrence Mitchell .  vf     - viewer and format structure (may be NULL if flg is FALSE)
360c8c899caSPeter Brune -  flg    - monitor or not
361c8c899caSPeter Brune 
362c8c899caSPeter Brune    Level: advanced
363c8c899caSPeter Brune 
364c8c899caSPeter Brune .keywords: FAS, monitor
365c8c899caSPeter Brune 
366c8c899caSPeter Brune .seealso: SNESFASSetCyclesOnLevel()
367c8c899caSPeter Brune @*/
368d142ab34SLawrence Mitchell PetscErrorCode SNESFASSetMonitor(SNES snes, PetscViewerAndFormat *vf, PetscBool flg)
36922d28d08SBarry Smith {
370c8c899caSPeter Brune   SNES_FAS       *fas = (SNES_FAS*)snes->data;
371c8c899caSPeter Brune   PetscErrorCode ierr;
372c8c899caSPeter Brune   PetscBool      isFine;
373c8c899caSPeter Brune   PetscInt       i, levels = fas->levels;
374c8c899caSPeter Brune   SNES           levelsnes;
37522d28d08SBarry Smith 
376c8c899caSPeter Brune   PetscFunctionBegin;
377c8c899caSPeter Brune   ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr);
378c8c899caSPeter Brune   if (isFine) {
379c8c899caSPeter Brune     for (i = 0; i < levels; i++) {
38022d28d08SBarry Smith       ierr = SNESFASGetCycleSNES(snes, i, &levelsnes);CHKERRQ(ierr);
381c8c899caSPeter Brune       fas  = (SNES_FAS*)levelsnes->data;
382c8c899caSPeter Brune       if (flg) {
383c8c899caSPeter Brune         /* set the monitors for the upsmoother and downsmoother */
384c8c899caSPeter Brune         ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr);
385d142ab34SLawrence Mitchell         /* Only register destroy on finest level */
386d142ab34SLawrence Mitchell         ierr = SNESMonitorSet(levelsnes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorDefault,vf,(!i ? (PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy : NULL));CHKERRQ(ierr);
3871aa26658SKarl Rupp       } else if (i != fas->levels - 1) {
388c8c899caSPeter Brune         /* unset the monitors on the coarse levels */
389c8c899caSPeter Brune         ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr);
390c8c899caSPeter Brune       }
391c8c899caSPeter Brune     }
392c8c899caSPeter Brune   }
393c8c899caSPeter Brune   PetscFunctionReturn(0);
394c8c899caSPeter Brune }
395c8c899caSPeter Brune 
3960dd27c6cSPeter Brune /*@
3970dd27c6cSPeter Brune    SNESFASSetLog - Sets or unsets time logging for various FAS stages on all levels
3980dd27c6cSPeter Brune 
3990dd27c6cSPeter Brune    Logically Collective on SNES
4000dd27c6cSPeter Brune 
4010dd27c6cSPeter Brune    Input Parameters:
4020dd27c6cSPeter Brune +  snes   - the FAS context
4030dd27c6cSPeter Brune -  flg    - monitor or not
4040dd27c6cSPeter Brune 
4050dd27c6cSPeter Brune    Level: advanced
4060dd27c6cSPeter Brune 
4070dd27c6cSPeter Brune .keywords: FAS, logging
4080dd27c6cSPeter Brune 
4090dd27c6cSPeter Brune .seealso: SNESFASSetMonitor()
4100dd27c6cSPeter Brune @*/
4110dd27c6cSPeter Brune PetscErrorCode SNESFASSetLog(SNES snes, PetscBool flg)
4120dd27c6cSPeter Brune {
4130dd27c6cSPeter Brune   SNES_FAS       *fas = (SNES_FAS*)snes->data;
4140dd27c6cSPeter Brune   PetscErrorCode ierr;
4150dd27c6cSPeter Brune   PetscBool      isFine;
4160dd27c6cSPeter Brune   PetscInt       i, levels = fas->levels;
4170dd27c6cSPeter Brune   SNES           levelsnes;
4180dd27c6cSPeter Brune   char           eventname[128];
4190dd27c6cSPeter Brune 
4200dd27c6cSPeter Brune   PetscFunctionBegin;
4210dd27c6cSPeter Brune   ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr);
4220dd27c6cSPeter Brune   if (isFine) {
4230dd27c6cSPeter Brune     for (i = 0; i < levels; i++) {
4240dd27c6cSPeter Brune       ierr = SNESFASGetCycleSNES(snes, i, &levelsnes);CHKERRQ(ierr);
4250dd27c6cSPeter Brune       fas  = (SNES_FAS*)levelsnes->data;
4260dd27c6cSPeter Brune       if (flg) {
4270dd27c6cSPeter Brune         sprintf(eventname,"FASSetup %d",(int)i);
4280dd27c6cSPeter Brune         ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsetup);CHKERRQ(ierr);
4290dd27c6cSPeter Brune         sprintf(eventname,"FASSmooth %d",(int)i);
4300dd27c6cSPeter Brune         ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsolve);CHKERRQ(ierr);
4310dd27c6cSPeter Brune         sprintf(eventname,"FASResid %d",(int)i);
4320dd27c6cSPeter Brune         ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventresidual);CHKERRQ(ierr);
4330dd27c6cSPeter Brune         if (i) {
4340dd27c6cSPeter Brune           sprintf(eventname,"FASInterp %d",(int)i);
4350dd27c6cSPeter Brune           ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventinterprestrict);CHKERRQ(ierr);
4360dd27c6cSPeter Brune         }
4370dd27c6cSPeter Brune       } else {
4380298fd71SBarry Smith         fas->eventsmoothsetup    = 0;
4390298fd71SBarry Smith         fas->eventsmoothsolve    = 0;
4400298fd71SBarry Smith         fas->eventresidual       = 0;
4410298fd71SBarry Smith         fas->eventinterprestrict = 0;
4420dd27c6cSPeter Brune       }
4430dd27c6cSPeter Brune     }
4440dd27c6cSPeter Brune   }
4450dd27c6cSPeter Brune   PetscFunctionReturn(0);
4460dd27c6cSPeter Brune }
4470dd27c6cSPeter Brune 
448ab8d36c9SPeter Brune /*
449ab8d36c9SPeter Brune Creates the default smoother type.
450ab8d36c9SPeter Brune 
45104d7464bSBarry Smith This is SNESNRICHARDSON on each fine level and SNESNEWTONLS on the coarse level.
452ab8d36c9SPeter Brune 
453ab8d36c9SPeter Brune  */
45422d28d08SBarry Smith PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES snes, SNES *smooth)
45522d28d08SBarry Smith {
456ab8d36c9SPeter Brune   SNES_FAS       *fas;
457ab8d36c9SPeter Brune   const char     *optionsprefix;
458ab8d36c9SPeter Brune   char           tprefix[128];
459ab8d36c9SPeter Brune   PetscErrorCode ierr;
460ab8d36c9SPeter Brune   SNES           nsmooth;
46122d28d08SBarry Smith 
462ab8d36c9SPeter Brune   PetscFunctionBegin;
463ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
464ab8d36c9SPeter Brune   fas  = (SNES_FAS*)snes->data;
465ab8d36c9SPeter Brune   ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr);
466ab8d36c9SPeter Brune   /* create the default smoother */
467ce94432eSBarry Smith   ierr = SNESCreate(PetscObjectComm((PetscObject)snes), &nsmooth);CHKERRQ(ierr);
468ab8d36c9SPeter Brune   if (fas->level == 0) {
469ab8d36c9SPeter Brune     sprintf(tprefix,"fas_coarse_");
470ab8d36c9SPeter Brune     ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr);
471ab8d36c9SPeter Brune     ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr);
47204d7464bSBarry Smith     ierr = SNESSetType(nsmooth, SNESNEWTONLS);CHKERRQ(ierr);
473e70c42e5SPeter Brune     ierr = SNESSetTolerances(nsmooth, nsmooth->abstol, nsmooth->rtol, nsmooth->stol, nsmooth->max_its, nsmooth->max_funcs);CHKERRQ(ierr);
474ab8d36c9SPeter Brune   } else {
475ab8d36c9SPeter Brune     sprintf(tprefix,"fas_levels_%d_",(int)fas->level);
476ab8d36c9SPeter Brune     ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr);
477ab8d36c9SPeter Brune     ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr);
478ab8d36c9SPeter Brune     ierr = SNESSetType(nsmooth, SNESNRICHARDSON);CHKERRQ(ierr);
479e70c42e5SPeter Brune     ierr = SNESSetTolerances(nsmooth, 0.0, 0.0, 0.0, fas->max_down_it, nsmooth->max_funcs);CHKERRQ(ierr);
480ab8d36c9SPeter Brune   }
481ab8d36c9SPeter Brune   ierr    = PetscObjectIncrementTabLevel((PetscObject)nsmooth, (PetscObject)snes, 1);CHKERRQ(ierr);
4823bb1ff40SBarry Smith   ierr    = PetscLogObjectParent((PetscObject)snes,(PetscObject)nsmooth);CHKERRQ(ierr);
483f89ba88eSPeter Brune   ierr    = PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)nsmooth);CHKERRQ(ierr);
484ab83eea4SMatthew G. Knepley   ierr    = PetscObjectComposedDataSetInt((PetscObject) nsmooth, PetscMGLevelId, fas->level);CHKERRQ(ierr);
485ab8d36c9SPeter Brune   *smooth = nsmooth;
486ab8d36c9SPeter Brune   PetscFunctionReturn(0);
487ab8d36c9SPeter Brune }
488ab8d36c9SPeter Brune 
489ab8d36c9SPeter Brune /* ------------- Functions called on a particular level ----------------- */
490ab8d36c9SPeter Brune 
491ab8d36c9SPeter Brune /*@
492ab8d36c9SPeter Brune    SNESFASCycleSetCycles - Sets the number of cycles on a particular level.
493ab8d36c9SPeter Brune 
494ab8d36c9SPeter Brune    Logically Collective on SNES
495ab8d36c9SPeter Brune 
496ab8d36c9SPeter Brune    Input Parameters:
497ab8d36c9SPeter Brune +  snes   - the multigrid context
498ab8d36c9SPeter Brune .  level  - the level to set the number of cycles on
499ab8d36c9SPeter Brune -  cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle
500ab8d36c9SPeter Brune 
501ab8d36c9SPeter Brune    Level: advanced
502ab8d36c9SPeter Brune 
503ab8d36c9SPeter Brune .keywords: SNES, FAS, set, cycles, V-cycle, W-cycle, multigrid
504ab8d36c9SPeter Brune 
505ab8d36c9SPeter Brune .seealso: SNESFASSetCycles()
506ab8d36c9SPeter Brune @*/
50722d28d08SBarry Smith PetscErrorCode SNESFASCycleSetCycles(SNES snes, PetscInt cycles)
50822d28d08SBarry Smith {
509ab8d36c9SPeter Brune   SNES_FAS       *fas =  (SNES_FAS*)snes->data;
510ab8d36c9SPeter Brune   PetscErrorCode ierr;
51122d28d08SBarry Smith 
512ab8d36c9SPeter Brune   PetscFunctionBegin;
513ab8d36c9SPeter Brune   fas->n_cycles = cycles;
514ab8d36c9SPeter Brune   ierr          = SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);CHKERRQ(ierr);
515ab8d36c9SPeter Brune   PetscFunctionReturn(0);
516ab8d36c9SPeter Brune }
517ab8d36c9SPeter Brune 
518ab8d36c9SPeter Brune 
519ab8d36c9SPeter Brune /*@
520ab8d36c9SPeter Brune    SNESFASCycleGetSmoother - Gets the smoother on a particular cycle level.
521ab8d36c9SPeter Brune 
522ab8d36c9SPeter Brune    Logically Collective on SNES
523ab8d36c9SPeter Brune 
524ab8d36c9SPeter Brune    Input Parameters:
525ab8d36c9SPeter Brune .  snes   - the multigrid context
526ab8d36c9SPeter Brune 
527ab8d36c9SPeter Brune    Output Parameters:
528ab8d36c9SPeter Brune .  smooth - the smoother
529ab8d36c9SPeter Brune 
530ab8d36c9SPeter Brune    Level: advanced
531ab8d36c9SPeter Brune 
532ab8d36c9SPeter Brune .keywords: SNES, FAS, get, smoother, multigrid
533ab8d36c9SPeter Brune 
534ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmootherDown()
535ab8d36c9SPeter Brune @*/
536ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetSmoother(SNES snes, SNES *smooth)
537ab8d36c9SPeter Brune {
538ab8d36c9SPeter Brune   SNES_FAS *fas;
5395fd66863SKarl Rupp 
540ab8d36c9SPeter Brune   PetscFunctionBegin;
541ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
542ab8d36c9SPeter Brune   fas     = (SNES_FAS*)snes->data;
543ab8d36c9SPeter Brune   *smooth = fas->smoothd;
544ab8d36c9SPeter Brune   PetscFunctionReturn(0);
545ab8d36c9SPeter Brune }
546ab8d36c9SPeter Brune /*@
547ab8d36c9SPeter Brune    SNESFASCycleGetSmootherUp - Gets the up smoother on a particular cycle level.
548ab8d36c9SPeter Brune 
549ab8d36c9SPeter Brune    Logically Collective on SNES
550ab8d36c9SPeter Brune 
551ab8d36c9SPeter Brune    Input Parameters:
552ab8d36c9SPeter Brune .  snes   - the multigrid context
553ab8d36c9SPeter Brune 
554ab8d36c9SPeter Brune    Output Parameters:
555ab8d36c9SPeter Brune .  smoothu - the smoother
556ab8d36c9SPeter Brune 
557ab8d36c9SPeter Brune    Notes:
558ab8d36c9SPeter Brune    Returns the downsmoother if no up smoother is available.  This enables transparent
559ab8d36c9SPeter Brune    default behavior in the process of the solve.
560ab8d36c9SPeter Brune 
561ab8d36c9SPeter Brune    Level: advanced
562ab8d36c9SPeter Brune 
563ab8d36c9SPeter Brune .keywords: SNES, FAS, get, smoother, multigrid
564ab8d36c9SPeter Brune 
565ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmoother(), SNESFASCycleGetSmootherDown()
566ab8d36c9SPeter Brune @*/
567ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetSmootherUp(SNES snes, SNES *smoothu)
568ab8d36c9SPeter Brune {
569ab8d36c9SPeter Brune   SNES_FAS *fas;
5705fd66863SKarl Rupp 
571ab8d36c9SPeter Brune   PetscFunctionBegin;
572ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
573ab8d36c9SPeter Brune   fas = (SNES_FAS*)snes->data;
5741aa26658SKarl Rupp   if (!fas->smoothu) *smoothu = fas->smoothd;
5751aa26658SKarl Rupp   else *smoothu = fas->smoothu;
576ab8d36c9SPeter Brune   PetscFunctionReturn(0);
577ab8d36c9SPeter Brune }
578ab8d36c9SPeter Brune 
579ab8d36c9SPeter Brune /*@
580ab8d36c9SPeter Brune    SNESFASCycleGetSmootherDown - Gets the down smoother on a particular cycle level.
581ab8d36c9SPeter Brune 
582ab8d36c9SPeter Brune    Logically Collective on SNES
583ab8d36c9SPeter Brune 
584ab8d36c9SPeter Brune    Input Parameters:
585ab8d36c9SPeter Brune .  snes   - the multigrid context
586ab8d36c9SPeter Brune 
587ab8d36c9SPeter Brune    Output Parameters:
588ab8d36c9SPeter Brune .  smoothd - the smoother
589ab8d36c9SPeter Brune 
590ab8d36c9SPeter Brune    Level: advanced
591ab8d36c9SPeter Brune 
592ab8d36c9SPeter Brune .keywords: SNES, FAS, get, smoother, multigrid
593ab8d36c9SPeter Brune 
594ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
595ab8d36c9SPeter Brune @*/
596ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetSmootherDown(SNES snes, SNES *smoothd)
597ab8d36c9SPeter Brune {
598ab8d36c9SPeter Brune   SNES_FAS *fas;
5995fd66863SKarl Rupp 
600ab8d36c9SPeter Brune   PetscFunctionBegin;
601ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
602ab8d36c9SPeter Brune   fas      = (SNES_FAS*)snes->data;
603ab8d36c9SPeter Brune   *smoothd = fas->smoothd;
604ab8d36c9SPeter Brune   PetscFunctionReturn(0);
605ab8d36c9SPeter Brune }
606ab8d36c9SPeter Brune 
607ab8d36c9SPeter Brune 
608ab8d36c9SPeter Brune /*@
609ab8d36c9SPeter Brune    SNESFASCycleGetCorrection - Gets the coarse correction FAS context for this level
610ab8d36c9SPeter Brune 
611ab8d36c9SPeter Brune    Logically Collective on SNES
612ab8d36c9SPeter Brune 
613ab8d36c9SPeter Brune    Input Parameters:
614ab8d36c9SPeter Brune .  snes   - the multigrid context
615ab8d36c9SPeter Brune 
616ab8d36c9SPeter Brune    Output Parameters:
617ab8d36c9SPeter Brune .  correction - the coarse correction on this level
618ab8d36c9SPeter Brune 
619ab8d36c9SPeter Brune    Notes:
6200298fd71SBarry Smith    Returns NULL on the coarsest level.
621ab8d36c9SPeter Brune 
622ab8d36c9SPeter Brune    Level: advanced
623ab8d36c9SPeter Brune 
624ab8d36c9SPeter Brune .keywords: SNES, FAS, get, smoother, multigrid
625ab8d36c9SPeter Brune 
626ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
627ab8d36c9SPeter Brune @*/
628ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetCorrection(SNES snes, SNES *correction)
629ab8d36c9SPeter Brune {
630ab8d36c9SPeter Brune   SNES_FAS *fas;
6315fd66863SKarl Rupp 
632ab8d36c9SPeter Brune   PetscFunctionBegin;
633ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
634ab8d36c9SPeter Brune   fas         = (SNES_FAS*)snes->data;
635ab8d36c9SPeter Brune   *correction = fas->next;
636ab8d36c9SPeter Brune   PetscFunctionReturn(0);
637ab8d36c9SPeter Brune }
638ab8d36c9SPeter Brune 
639ab8d36c9SPeter Brune /*@
640ab8d36c9SPeter Brune    SNESFASCycleGetInterpolation - Gets the interpolation on this level
641ab8d36c9SPeter Brune 
642ab8d36c9SPeter Brune    Logically Collective on SNES
643ab8d36c9SPeter Brune 
644ab8d36c9SPeter Brune    Input Parameters:
645ab8d36c9SPeter Brune .  snes   - the multigrid context
646ab8d36c9SPeter Brune 
647ab8d36c9SPeter Brune    Output Parameters:
648ab8d36c9SPeter Brune .  mat    - the interpolation operator on this level
649ab8d36c9SPeter Brune 
650ab8d36c9SPeter Brune    Level: developer
651ab8d36c9SPeter Brune 
652ab8d36c9SPeter Brune .keywords: SNES, FAS, get, smoother, multigrid
653ab8d36c9SPeter Brune 
654ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
655ab8d36c9SPeter Brune @*/
656ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetInterpolation(SNES snes, Mat *mat)
657ab8d36c9SPeter Brune {
658ab8d36c9SPeter Brune   SNES_FAS *fas;
6595fd66863SKarl Rupp 
660ab8d36c9SPeter Brune   PetscFunctionBegin;
661ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
662ab8d36c9SPeter Brune   fas  = (SNES_FAS*)snes->data;
663ab8d36c9SPeter Brune   *mat = fas->interpolate;
664ab8d36c9SPeter Brune   PetscFunctionReturn(0);
665ab8d36c9SPeter Brune }
666ab8d36c9SPeter Brune 
667ab8d36c9SPeter Brune 
668ab8d36c9SPeter Brune /*@
669ab8d36c9SPeter Brune    SNESFASCycleGetRestriction - Gets the restriction on this level
670ab8d36c9SPeter Brune 
671ab8d36c9SPeter Brune    Logically Collective on SNES
672ab8d36c9SPeter Brune 
673ab8d36c9SPeter Brune    Input Parameters:
674ab8d36c9SPeter Brune .  snes   - the multigrid context
675ab8d36c9SPeter Brune 
676ab8d36c9SPeter Brune    Output Parameters:
677ab8d36c9SPeter Brune .  mat    - the restriction operator on this level
678ab8d36c9SPeter Brune 
679ab8d36c9SPeter Brune    Level: developer
680ab8d36c9SPeter Brune 
681ab8d36c9SPeter Brune .keywords: SNES, FAS, get, smoother, multigrid
682ab8d36c9SPeter Brune 
683ab8d36c9SPeter Brune .seealso: SNESFASGetRestriction(), SNESFASCycleGetInterpolation()
684ab8d36c9SPeter Brune @*/
685ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetRestriction(SNES snes, Mat *mat)
686ab8d36c9SPeter Brune {
687ab8d36c9SPeter Brune   SNES_FAS *fas;
6885fd66863SKarl Rupp 
689ab8d36c9SPeter Brune   PetscFunctionBegin;
690ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
691ab8d36c9SPeter Brune   fas  = (SNES_FAS*)snes->data;
692ab8d36c9SPeter Brune   *mat = fas->restrct;
693ab8d36c9SPeter Brune   PetscFunctionReturn(0);
694ab8d36c9SPeter Brune }
695ab8d36c9SPeter Brune 
696ab8d36c9SPeter Brune 
697ab8d36c9SPeter Brune /*@
698ab8d36c9SPeter Brune    SNESFASCycleGetInjection - Gets the injection on this level
699ab8d36c9SPeter Brune 
700ab8d36c9SPeter Brune    Logically Collective on SNES
701ab8d36c9SPeter Brune 
702ab8d36c9SPeter Brune    Input Parameters:
703ab8d36c9SPeter Brune .  snes   - the multigrid context
704ab8d36c9SPeter Brune 
705ab8d36c9SPeter Brune    Output Parameters:
706ab8d36c9SPeter Brune .  mat    - the restriction operator on this level
707ab8d36c9SPeter Brune 
708ab8d36c9SPeter Brune    Level: developer
709ab8d36c9SPeter Brune 
710ab8d36c9SPeter Brune .keywords: SNES, FAS, get, smoother, multigrid
711ab8d36c9SPeter Brune 
712ab8d36c9SPeter Brune .seealso: SNESFASGetInjection(), SNESFASCycleGetRestriction()
713ab8d36c9SPeter Brune @*/
714ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetInjection(SNES snes, Mat *mat)
715ab8d36c9SPeter Brune {
716ab8d36c9SPeter Brune   SNES_FAS *fas;
7175fd66863SKarl Rupp 
718ab8d36c9SPeter Brune   PetscFunctionBegin;
719ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
720ab8d36c9SPeter Brune   fas  = (SNES_FAS*)snes->data;
721ab8d36c9SPeter Brune   *mat = fas->inject;
722ab8d36c9SPeter Brune   PetscFunctionReturn(0);
723ab8d36c9SPeter Brune }
724ab8d36c9SPeter Brune 
725ab8d36c9SPeter Brune /*@
726ab8d36c9SPeter Brune    SNESFASCycleGetRScale - Gets the injection on this level
727ab8d36c9SPeter Brune 
728ab8d36c9SPeter Brune    Logically Collective on SNES
729ab8d36c9SPeter Brune 
730ab8d36c9SPeter Brune    Input Parameters:
731ab8d36c9SPeter Brune .  snes   - the multigrid context
732ab8d36c9SPeter Brune 
733ab8d36c9SPeter Brune    Output Parameters:
734ab8d36c9SPeter Brune .  mat    - the restriction operator on this level
735ab8d36c9SPeter Brune 
736ab8d36c9SPeter Brune    Level: developer
737ab8d36c9SPeter Brune 
738ab8d36c9SPeter Brune .keywords: SNES, FAS, get, smoother, multigrid
739ab8d36c9SPeter Brune 
740ab8d36c9SPeter Brune .seealso: SNESFASCycleGetRestriction(), SNESFASGetRScale()
741ab8d36c9SPeter Brune @*/
742ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetRScale(SNES snes, Vec *vec)
743ab8d36c9SPeter Brune {
744ab8d36c9SPeter Brune   SNES_FAS *fas;
7455fd66863SKarl Rupp 
746ab8d36c9SPeter Brune   PetscFunctionBegin;
747ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
748ab8d36c9SPeter Brune   fas  = (SNES_FAS*)snes->data;
749ab8d36c9SPeter Brune   *vec = fas->rscale;
750ab8d36c9SPeter Brune   PetscFunctionReturn(0);
751ab8d36c9SPeter Brune }
752ab8d36c9SPeter Brune 
753ab8d36c9SPeter Brune /*@
754ab8d36c9SPeter Brune    SNESFASCycleIsFine - Determines if a given cycle is the fine level.
755ab8d36c9SPeter Brune 
756ab8d36c9SPeter Brune    Logically Collective on SNES
757ab8d36c9SPeter Brune 
758ab8d36c9SPeter Brune    Input Parameters:
759ab8d36c9SPeter Brune .  snes   - the FAS context
760ab8d36c9SPeter Brune 
761ab8d36c9SPeter Brune    Output Parameters:
762ab8d36c9SPeter Brune .  flg - indicates if this is the fine level or not
763ab8d36c9SPeter Brune 
764ab8d36c9SPeter Brune    Level: advanced
765ab8d36c9SPeter Brune 
766ab8d36c9SPeter Brune .keywords: SNES, FAS
767ab8d36c9SPeter Brune 
768ab8d36c9SPeter Brune .seealso: SNESFASSetLevels()
769ab8d36c9SPeter Brune @*/
770ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleIsFine(SNES snes, PetscBool *flg)
771ab8d36c9SPeter Brune {
772ab8d36c9SPeter Brune   SNES_FAS *fas;
7735fd66863SKarl Rupp 
774ab8d36c9SPeter Brune   PetscFunctionBegin;
775ab8d36c9SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
776ab8d36c9SPeter Brune   fas = (SNES_FAS*)snes->data;
7771aa26658SKarl Rupp   if (fas->level == fas->levels - 1) *flg = PETSC_TRUE;
7781aa26658SKarl Rupp   else *flg = PETSC_FALSE;
779ab8d36c9SPeter Brune   PetscFunctionReturn(0);
780ab8d36c9SPeter Brune }
781ab8d36c9SPeter Brune 
782ab8d36c9SPeter Brune /* ---------- functions called on the finest level that return level-specific information ---------- */
783ab8d36c9SPeter Brune 
784ab8d36c9SPeter Brune /*@
785ab8d36c9SPeter Brune    SNESFASSetInterpolation - Sets the function to be used to calculate the
786ab8d36c9SPeter Brune    interpolation from l-1 to the lth level
787ab8d36c9SPeter Brune 
788ab8d36c9SPeter Brune    Input Parameters:
789ab8d36c9SPeter Brune +  snes      - the multigrid context
790ab8d36c9SPeter Brune .  mat       - the interpolation operator
791ab8d36c9SPeter Brune -  level     - the level (0 is coarsest) to supply [do not supply 0]
792ab8d36c9SPeter Brune 
793ab8d36c9SPeter Brune    Level: advanced
794ab8d36c9SPeter Brune 
795ab8d36c9SPeter Brune    Notes:
796ab8d36c9SPeter Brune           Usually this is the same matrix used also to set the restriction
797ab8d36c9SPeter Brune     for the same level.
798ab8d36c9SPeter Brune 
799ab8d36c9SPeter Brune           One can pass in the interpolation matrix or its transpose; PETSc figures
800ab8d36c9SPeter Brune     out from the matrix size which one it is.
801ab8d36c9SPeter Brune 
802ab8d36c9SPeter Brune .keywords:  FAS, multigrid, set, interpolate, level
803ab8d36c9SPeter Brune 
804ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction(), SNESFASSetRScale()
805ab8d36c9SPeter Brune @*/
8060adebc6cSBarry Smith PetscErrorCode SNESFASSetInterpolation(SNES snes, PetscInt level, Mat mat)
8070adebc6cSBarry Smith {
80822d28d08SBarry Smith   SNES_FAS       *fas;
809ab8d36c9SPeter Brune   PetscErrorCode ierr;
810ab8d36c9SPeter Brune   SNES           levelsnes;
81122d28d08SBarry Smith 
812ab8d36c9SPeter Brune   PetscFunctionBegin;
813ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
814ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
815ab8d36c9SPeter Brune   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
816ab8d36c9SPeter Brune   ierr = MatDestroy(&fas->interpolate);CHKERRQ(ierr);
8171aa26658SKarl Rupp 
818ab8d36c9SPeter Brune   fas->interpolate = mat;
819ab8d36c9SPeter Brune   PetscFunctionReturn(0);
820ab8d36c9SPeter Brune }
821ab8d36c9SPeter Brune 
822ab8d36c9SPeter Brune /*@
823ab8d36c9SPeter Brune    SNESFASGetInterpolation - Gets the matrix used to calculate the
824ab8d36c9SPeter Brune    interpolation from l-1 to the lth level
825ab8d36c9SPeter Brune 
826ab8d36c9SPeter Brune    Input Parameters:
827ab8d36c9SPeter Brune +  snes      - the multigrid context
828ab8d36c9SPeter Brune -  level     - the level (0 is coarsest) to supply [do not supply 0]
829ab8d36c9SPeter Brune 
830ab8d36c9SPeter Brune    Output Parameters:
831ab8d36c9SPeter Brune .  mat       - the interpolation operator
832ab8d36c9SPeter Brune 
833ab8d36c9SPeter Brune    Level: advanced
834ab8d36c9SPeter Brune 
835ab8d36c9SPeter Brune .keywords:  FAS, multigrid, get, interpolate, level
836ab8d36c9SPeter Brune 
837ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASGetInjection(), SNESFASGetRestriction(), SNESFASGetRScale()
838ab8d36c9SPeter Brune @*/
83922d28d08SBarry Smith PetscErrorCode SNESFASGetInterpolation(SNES snes, PetscInt level, Mat *mat)
84022d28d08SBarry Smith {
84122d28d08SBarry Smith   SNES_FAS       *fas;
842ab8d36c9SPeter Brune   PetscErrorCode ierr;
843ab8d36c9SPeter Brune   SNES           levelsnes;
84422d28d08SBarry Smith 
845ab8d36c9SPeter Brune   PetscFunctionBegin;
846ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
847ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
848ab8d36c9SPeter Brune   *mat = fas->interpolate;
849ab8d36c9SPeter Brune   PetscFunctionReturn(0);
850ab8d36c9SPeter Brune }
851ab8d36c9SPeter Brune 
852ab8d36c9SPeter Brune /*@
853ab8d36c9SPeter Brune    SNESFASSetRestriction - Sets the function to be used to restrict the defect
854ab8d36c9SPeter Brune    from level l to l-1.
855ab8d36c9SPeter Brune 
856ab8d36c9SPeter Brune    Input Parameters:
857ab8d36c9SPeter Brune +  snes  - the multigrid context
858ab8d36c9SPeter Brune .  mat   - the restriction matrix
859ab8d36c9SPeter Brune -  level - the level (0 is coarsest) to supply [Do not supply 0]
860ab8d36c9SPeter Brune 
861ab8d36c9SPeter Brune    Level: advanced
862ab8d36c9SPeter Brune 
863ab8d36c9SPeter Brune    Notes:
864ab8d36c9SPeter Brune           Usually this is the same matrix used also to set the interpolation
865ab8d36c9SPeter Brune     for the same level.
866ab8d36c9SPeter Brune 
867ab8d36c9SPeter Brune           One can pass in the interpolation matrix or its transpose; PETSc figures
868ab8d36c9SPeter Brune     out from the matrix size which one it is.
869ab8d36c9SPeter Brune 
870ab8d36c9SPeter Brune          If you do not set this, the transpose of the Mat set with SNESFASSetInterpolation()
871ab8d36c9SPeter Brune     is used.
872ab8d36c9SPeter Brune 
873ab8d36c9SPeter Brune .keywords: FAS, MG, set, multigrid, restriction, level
874ab8d36c9SPeter Brune 
875ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASSetInjection()
876ab8d36c9SPeter Brune @*/
87722d28d08SBarry Smith PetscErrorCode SNESFASSetRestriction(SNES snes, PetscInt level, Mat mat)
87822d28d08SBarry Smith {
87922d28d08SBarry Smith   SNES_FAS       *fas;
880ab8d36c9SPeter Brune   PetscErrorCode ierr;
881ab8d36c9SPeter Brune   SNES           levelsnes;
88222d28d08SBarry Smith 
883ab8d36c9SPeter Brune   PetscFunctionBegin;
884ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
885ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
886ab8d36c9SPeter Brune   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
887ab8d36c9SPeter Brune   ierr = MatDestroy(&fas->restrct);CHKERRQ(ierr);
8881aa26658SKarl Rupp 
889ab8d36c9SPeter Brune   fas->restrct = mat;
890ab8d36c9SPeter Brune   PetscFunctionReturn(0);
891ab8d36c9SPeter Brune }
892ab8d36c9SPeter Brune 
893ab8d36c9SPeter Brune /*@
894ab8d36c9SPeter Brune    SNESFASGetRestriction - Gets the matrix used to calculate the
895ab8d36c9SPeter Brune    restriction from l to the l-1th level
896ab8d36c9SPeter Brune 
897ab8d36c9SPeter Brune    Input Parameters:
898ab8d36c9SPeter Brune +  snes      - the multigrid context
899ab8d36c9SPeter Brune -  level     - the level (0 is coarsest) to supply [do not supply 0]
900ab8d36c9SPeter Brune 
901ab8d36c9SPeter Brune    Output Parameters:
902ab8d36c9SPeter Brune .  mat       - the interpolation operator
903ab8d36c9SPeter Brune 
904ab8d36c9SPeter Brune    Level: advanced
905ab8d36c9SPeter Brune 
906ab8d36c9SPeter Brune .keywords:  FAS, multigrid, get, restrict, level
907ab8d36c9SPeter Brune 
908ab8d36c9SPeter Brune .seealso: SNESFASSetRestriction(), SNESFASGetInjection(), SNESFASGetInterpolation(), SNESFASGetRScale()
909ab8d36c9SPeter Brune @*/
91022d28d08SBarry Smith PetscErrorCode SNESFASGetRestriction(SNES snes, PetscInt level, Mat *mat)
91122d28d08SBarry Smith {
91222d28d08SBarry Smith   SNES_FAS       *fas;
913ab8d36c9SPeter Brune   PetscErrorCode ierr;
914ab8d36c9SPeter Brune   SNES           levelsnes;
91522d28d08SBarry Smith 
916ab8d36c9SPeter Brune   PetscFunctionBegin;
917ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
918ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
919ab8d36c9SPeter Brune   *mat = fas->restrct;
920ab8d36c9SPeter Brune   PetscFunctionReturn(0);
921ab8d36c9SPeter Brune }
922ab8d36c9SPeter Brune 
923ab8d36c9SPeter Brune 
924ab8d36c9SPeter Brune /*@
925ab8d36c9SPeter Brune    SNESFASSetInjection - Sets the function to be used to inject the solution
926ab8d36c9SPeter Brune    from level l to l-1.
927ab8d36c9SPeter Brune 
928ab8d36c9SPeter Brune    Input Parameters:
929ab8d36c9SPeter Brune  +  snes  - the multigrid context
930ab8d36c9SPeter Brune .  mat   - the restriction matrix
931ab8d36c9SPeter Brune -  level - the level (0 is coarsest) to supply [Do not supply 0]
932ab8d36c9SPeter Brune 
933ab8d36c9SPeter Brune    Level: advanced
934ab8d36c9SPeter Brune 
935ab8d36c9SPeter Brune    Notes:
936ab8d36c9SPeter Brune          If you do not set this, the restriction and rscale is used to
937ab8d36c9SPeter Brune    project the solution instead.
938ab8d36c9SPeter Brune 
939ab8d36c9SPeter Brune .keywords: FAS, MG, set, multigrid, restriction, level
940ab8d36c9SPeter Brune 
941ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASSetRestriction()
942ab8d36c9SPeter Brune @*/
94322d28d08SBarry Smith PetscErrorCode SNESFASSetInjection(SNES snes, PetscInt level, Mat mat)
94422d28d08SBarry Smith {
94522d28d08SBarry Smith   SNES_FAS       *fas;
946ab8d36c9SPeter Brune   PetscErrorCode ierr;
947ab8d36c9SPeter Brune   SNES           levelsnes;
94822d28d08SBarry Smith 
949ab8d36c9SPeter Brune   PetscFunctionBegin;
950ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
951ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
952ab8d36c9SPeter Brune   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
953ab8d36c9SPeter Brune   ierr = MatDestroy(&fas->inject);CHKERRQ(ierr);
9541aa26658SKarl Rupp 
955ab8d36c9SPeter Brune   fas->inject = mat;
956ab8d36c9SPeter Brune   PetscFunctionReturn(0);
957ab8d36c9SPeter Brune }
958ab8d36c9SPeter Brune 
959ab8d36c9SPeter Brune 
960ab8d36c9SPeter Brune /*@
961ab8d36c9SPeter Brune    SNESFASGetInjection - Gets the matrix used to calculate the
962ab8d36c9SPeter Brune    injection from l-1 to the lth level
963ab8d36c9SPeter Brune 
964ab8d36c9SPeter Brune    Input Parameters:
965ab8d36c9SPeter Brune +  snes      - the multigrid context
966ab8d36c9SPeter Brune -  level     - the level (0 is coarsest) to supply [do not supply 0]
967ab8d36c9SPeter Brune 
968ab8d36c9SPeter Brune    Output Parameters:
969ab8d36c9SPeter Brune .  mat       - the injection operator
970ab8d36c9SPeter Brune 
971ab8d36c9SPeter Brune    Level: advanced
972ab8d36c9SPeter Brune 
973ab8d36c9SPeter Brune .keywords:  FAS, multigrid, get, restrict, level
974ab8d36c9SPeter Brune 
975ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASGetRestriction(), SNESFASGetInterpolation(), SNESFASGetRScale()
976ab8d36c9SPeter Brune @*/
97722d28d08SBarry Smith PetscErrorCode SNESFASGetInjection(SNES snes, PetscInt level, Mat *mat)
97822d28d08SBarry Smith {
97922d28d08SBarry Smith   SNES_FAS       *fas;
980ab8d36c9SPeter Brune   PetscErrorCode ierr;
981ab8d36c9SPeter Brune   SNES           levelsnes;
98222d28d08SBarry Smith 
983ab8d36c9SPeter Brune   PetscFunctionBegin;
984ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
985ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
986ab8d36c9SPeter Brune   *mat = fas->inject;
987ab8d36c9SPeter Brune   PetscFunctionReturn(0);
988ab8d36c9SPeter Brune }
989ab8d36c9SPeter Brune 
990ab8d36c9SPeter Brune /*@
991ab8d36c9SPeter Brune    SNESFASSetRScale - Sets the scaling factor of the restriction
992ab8d36c9SPeter Brune    operator from level l to l-1.
993ab8d36c9SPeter Brune 
994ab8d36c9SPeter Brune    Input Parameters:
995ab8d36c9SPeter Brune +  snes   - the multigrid context
996ab8d36c9SPeter Brune .  rscale - the restriction scaling
997ab8d36c9SPeter Brune -  level  - the level (0 is coarsest) to supply [Do not supply 0]
998ab8d36c9SPeter Brune 
999ab8d36c9SPeter Brune    Level: advanced
1000ab8d36c9SPeter Brune 
1001ab8d36c9SPeter Brune    Notes:
1002ab8d36c9SPeter Brune          This is only used in the case that the injection is not set.
1003ab8d36c9SPeter Brune 
1004ab8d36c9SPeter Brune .keywords: FAS, MG, set, multigrid, restriction, level
1005ab8d36c9SPeter Brune 
1006ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1007ab8d36c9SPeter Brune @*/
100822d28d08SBarry Smith PetscErrorCode SNESFASSetRScale(SNES snes, PetscInt level, Vec rscale)
100922d28d08SBarry Smith {
1010ab8d36c9SPeter Brune   SNES_FAS       *fas;
1011ab8d36c9SPeter Brune   PetscErrorCode ierr;
1012ab8d36c9SPeter Brune   SNES           levelsnes;
101322d28d08SBarry Smith 
1014ab8d36c9SPeter Brune   PetscFunctionBegin;
1015ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
1016ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1017ab8d36c9SPeter Brune   ierr = PetscObjectReference((PetscObject)rscale);CHKERRQ(ierr);
1018ab8d36c9SPeter Brune   ierr = VecDestroy(&fas->rscale);CHKERRQ(ierr);
10191aa26658SKarl Rupp 
1020ab8d36c9SPeter Brune   fas->rscale = rscale;
1021ab8d36c9SPeter Brune   PetscFunctionReturn(0);
1022ab8d36c9SPeter Brune }
1023ab8d36c9SPeter Brune 
1024ab8d36c9SPeter Brune /*@
1025ab8d36c9SPeter Brune    SNESFASGetSmoother - Gets the default smoother on a level.
1026ab8d36c9SPeter Brune 
1027ab8d36c9SPeter Brune    Input Parameters:
1028ab8d36c9SPeter Brune +  snes   - the multigrid context
1029ab8d36c9SPeter Brune -  level  - the level (0 is coarsest) to supply
1030ab8d36c9SPeter Brune 
1031ab8d36c9SPeter Brune    Output Parameters:
1032ab8d36c9SPeter Brune    smooth  - the smoother
1033ab8d36c9SPeter Brune 
1034ab8d36c9SPeter Brune    Level: advanced
1035ab8d36c9SPeter Brune 
1036ab8d36c9SPeter Brune .keywords: FAS, MG, get, multigrid, smoother, level
1037ab8d36c9SPeter Brune 
1038ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1039ab8d36c9SPeter Brune @*/
104022d28d08SBarry Smith PetscErrorCode SNESFASGetSmoother(SNES snes, PetscInt level, SNES *smooth)
104122d28d08SBarry Smith {
1042ab8d36c9SPeter Brune   SNES_FAS       *fas;
1043ab8d36c9SPeter Brune   PetscErrorCode ierr;
1044ab8d36c9SPeter Brune   SNES           levelsnes;
104522d28d08SBarry Smith 
1046ab8d36c9SPeter Brune   PetscFunctionBegin;
1047ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
1048ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1049ab8d36c9SPeter Brune   if (!fas->smoothd) {
10503de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr);
1051ab8d36c9SPeter Brune   }
1052ab8d36c9SPeter Brune   *smooth = fas->smoothd;
1053ab8d36c9SPeter Brune   PetscFunctionReturn(0);
1054ab8d36c9SPeter Brune }
1055ab8d36c9SPeter Brune 
1056ab8d36c9SPeter Brune /*@
1057ab8d36c9SPeter Brune    SNESFASGetSmootherDown - Gets the downsmoother on a level.
1058ab8d36c9SPeter Brune 
1059ab8d36c9SPeter Brune    Input Parameters:
1060ab8d36c9SPeter Brune +  snes   - the multigrid context
1061ab8d36c9SPeter Brune -  level  - the level (0 is coarsest) to supply
1062ab8d36c9SPeter Brune 
1063ab8d36c9SPeter Brune    Output Parameters:
1064ab8d36c9SPeter Brune    smooth  - the smoother
1065ab8d36c9SPeter Brune 
1066ab8d36c9SPeter Brune    Level: advanced
1067ab8d36c9SPeter Brune 
1068ab8d36c9SPeter Brune .keywords: FAS, MG, get, multigrid, smoother, level
1069ab8d36c9SPeter Brune 
1070ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1071ab8d36c9SPeter Brune @*/
107222d28d08SBarry Smith PetscErrorCode SNESFASGetSmootherDown(SNES snes, PetscInt level, SNES *smooth)
107322d28d08SBarry Smith {
1074ab8d36c9SPeter Brune   SNES_FAS       *fas;
1075ab8d36c9SPeter Brune   PetscErrorCode ierr;
1076ab8d36c9SPeter Brune   SNES           levelsnes;
107722d28d08SBarry Smith 
1078ab8d36c9SPeter Brune   PetscFunctionBegin;
1079ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
1080ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1081ab8d36c9SPeter Brune   /* if the user chooses to differentiate smoothers, create them both at this point */
1082ab8d36c9SPeter Brune   if (!fas->smoothd) {
10833de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr);
1084ab8d36c9SPeter Brune   }
1085ab8d36c9SPeter Brune   if (!fas->smoothu) {
10863de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);CHKERRQ(ierr);
1087ab8d36c9SPeter Brune   }
1088ab8d36c9SPeter Brune   *smooth = fas->smoothd;
1089ab8d36c9SPeter Brune   PetscFunctionReturn(0);
1090ab8d36c9SPeter Brune }
1091ab8d36c9SPeter Brune 
1092ab8d36c9SPeter Brune /*@
1093ab8d36c9SPeter Brune    SNESFASGetSmootherUp - Gets the upsmoother on a level.
1094ab8d36c9SPeter Brune 
1095ab8d36c9SPeter Brune    Input Parameters:
1096ab8d36c9SPeter Brune +  snes   - the multigrid context
1097ab8d36c9SPeter Brune -  level  - the level (0 is coarsest)
1098ab8d36c9SPeter Brune 
1099ab8d36c9SPeter Brune    Output Parameters:
1100ab8d36c9SPeter Brune    smooth  - the smoother
1101ab8d36c9SPeter Brune 
1102ab8d36c9SPeter Brune    Level: advanced
1103ab8d36c9SPeter Brune 
1104ab8d36c9SPeter Brune .keywords: FAS, MG, get, multigrid, smoother, level
1105ab8d36c9SPeter Brune 
1106ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1107ab8d36c9SPeter Brune @*/
110822d28d08SBarry Smith PetscErrorCode SNESFASGetSmootherUp(SNES snes, PetscInt level, SNES *smooth)
110922d28d08SBarry Smith {
1110ab8d36c9SPeter Brune   SNES_FAS       *fas;
1111ab8d36c9SPeter Brune   PetscErrorCode ierr;
1112ab8d36c9SPeter Brune   SNES           levelsnes;
111322d28d08SBarry Smith 
1114ab8d36c9SPeter Brune   PetscFunctionBegin;
1115ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
1116ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1117ab8d36c9SPeter Brune   /* if the user chooses to differentiate smoothers, create them both at this point */
1118ab8d36c9SPeter Brune   if (!fas->smoothd) {
11193de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr);
1120ab8d36c9SPeter Brune   }
1121ab8d36c9SPeter Brune   if (!fas->smoothu) {
11223de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);CHKERRQ(ierr);
1123ab8d36c9SPeter Brune   }
1124ab8d36c9SPeter Brune   *smooth = fas->smoothu;
1125ab8d36c9SPeter Brune   PetscFunctionReturn(0);
1126ab8d36c9SPeter Brune }
1127d6ad1212SPeter Brune 
1128d6ad1212SPeter Brune /*@
1129d6ad1212SPeter Brune   SNESFASGetCoarseSolve - Gets the coarsest solver.
1130d6ad1212SPeter Brune 
1131d6ad1212SPeter Brune   Input Parameters:
1132a3a80b83SMatthew G. Knepley . snes - the multigrid context
1133d6ad1212SPeter Brune 
1134d6ad1212SPeter Brune   Output Parameters:
1135a3a80b83SMatthew G. Knepley . coarse - the coarse-level solver
1136d6ad1212SPeter Brune 
1137d6ad1212SPeter Brune   Level: advanced
1138d6ad1212SPeter Brune 
1139d6ad1212SPeter Brune .keywords: FAS, MG, get, multigrid, solver, coarse
1140d6ad1212SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1141d6ad1212SPeter Brune @*/
1142a3a80b83SMatthew G. Knepley PetscErrorCode SNESFASGetCoarseSolve(SNES snes, SNES *coarse)
114322d28d08SBarry Smith {
1144d6ad1212SPeter Brune   SNES_FAS       *fas;
1145d6ad1212SPeter Brune   PetscErrorCode ierr;
1146d6ad1212SPeter Brune   SNES           levelsnes;
114722d28d08SBarry Smith 
1148d6ad1212SPeter Brune   PetscFunctionBegin;
1149d6ad1212SPeter Brune   ierr = SNESFASGetCycleSNES(snes, 0, &levelsnes);CHKERRQ(ierr);
1150d6ad1212SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1151d6ad1212SPeter Brune   /* if the user chooses to differentiate smoothers, create them both at this point */
1152d6ad1212SPeter Brune   if (!fas->smoothd) {
11533de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr);
1154d6ad1212SPeter Brune   }
1155a3a80b83SMatthew G. Knepley   *coarse = fas->smoothd;
1156d6ad1212SPeter Brune   PetscFunctionReturn(0);
1157d6ad1212SPeter Brune }
1158928e959bSPeter Brune 
1159928e959bSPeter Brune /*@
1160928e959bSPeter Brune    SNESFASFullSetDownSweep - Smooth during the initial downsweep for SNESFAS
1161928e959bSPeter Brune 
1162928e959bSPeter Brune    Logically Collective on SNES
1163928e959bSPeter Brune 
1164928e959bSPeter Brune    Input Parameters:
1165928e959bSPeter Brune +  snes - the multigrid context
1166928e959bSPeter Brune -  swp - whether to downsweep or not
1167928e959bSPeter Brune 
1168928e959bSPeter Brune    Options Database Key:
1169928e959bSPeter Brune .  -snes_fas_full_downsweep - Sets number of pre-smoothing steps
1170928e959bSPeter Brune 
1171928e959bSPeter Brune    Level: advanced
1172928e959bSPeter Brune 
1173928e959bSPeter Brune .keywords: FAS, MG, smooth, down, pre-smoothing, steps, multigrid
1174928e959bSPeter Brune 
1175928e959bSPeter Brune .seealso: SNESFASSetNumberSmoothUp()
1176928e959bSPeter Brune @*/
1177928e959bSPeter Brune PetscErrorCode SNESFASFullSetDownSweep(SNES snes,PetscBool swp)
1178928e959bSPeter Brune {
1179928e959bSPeter Brune   SNES_FAS       *fas =  (SNES_FAS*)snes->data;
1180928e959bSPeter Brune   PetscErrorCode ierr = 0;
1181928e959bSPeter Brune 
1182928e959bSPeter Brune   PetscFunctionBegin;
1183928e959bSPeter Brune   fas->full_downsweep = swp;
1184928e959bSPeter Brune   if (fas->next) {
1185928e959bSPeter Brune     ierr = SNESFASFullSetDownSweep(fas->next,swp);CHKERRQ(ierr);
1186928e959bSPeter Brune   }
1187928e959bSPeter Brune   PetscFunctionReturn(0);
1188928e959bSPeter Brune }
1189