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