xref: /petsc/src/snes/impls/fas/fasfunc.c (revision 534a8f05a7a8aff70dd8cfd53d9cd834400a8dbf)
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 {
21f833ba53SLisandro Dalcin   SNES_FAS       *fas;
22ab8d36c9SPeter Brune   PetscErrorCode ierr;
2322d28d08SBarry Smith 
24ab8d36c9SPeter Brune   PetscFunctionBegin;
25f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
26ab8d36c9SPeter Brune   PetscValidLogicalCollectiveEnum(snes,fastype,2);
27f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
28ab8d36c9SPeter Brune   fas->fastype = fastype;
2922d28d08SBarry Smith   if (fas->next) {
3022d28d08SBarry Smith     ierr = SNESFASSetType(fas->next, fastype);CHKERRQ(ierr);
3122d28d08SBarry Smith   }
32ab8d36c9SPeter Brune   PetscFunctionReturn(0);
33ab8d36c9SPeter Brune }
34ab8d36c9SPeter Brune 
35ab8d36c9SPeter Brune 
36ab8d36c9SPeter Brune /*@
37ab8d36c9SPeter Brune SNESFASGetType - Sets the update and correction type used for FAS.
38ab8d36c9SPeter Brune 
39ab8d36c9SPeter Brune Logically Collective
40ab8d36c9SPeter Brune 
41ab8d36c9SPeter Brune Input Parameters:
42ab8d36c9SPeter Brune . snes - FAS context
43ab8d36c9SPeter Brune 
44ab8d36c9SPeter Brune Output Parameters:
45ab8d36c9SPeter Brune . fastype - SNES_FAS_ADDITIVE or SNES_FAS_MULTIPLICATIVE
46ab8d36c9SPeter Brune 
47583a1250SSatish Balay Level: intermediate
48583a1250SSatish Balay 
49ab8d36c9SPeter Brune .seealso: PCMGSetType()
50ab8d36c9SPeter Brune @*/
51ab8d36c9SPeter Brune PetscErrorCode  SNESFASGetType(SNES snes,SNESFASType *fastype)
52ab8d36c9SPeter Brune {
53f833ba53SLisandro Dalcin   SNES_FAS *fas;
54ab8d36c9SPeter Brune 
55ab8d36c9SPeter Brune   PetscFunctionBegin;
56f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
57ab8d36c9SPeter Brune   PetscValidPointer(fastype, 2);
58f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
59ab8d36c9SPeter Brune   *fastype = fas->fastype;
60ab8d36c9SPeter Brune   PetscFunctionReturn(0);
61ab8d36c9SPeter Brune }
62ab8d36c9SPeter Brune 
63ab8d36c9SPeter Brune /*@C
64ab8d36c9SPeter Brune    SNESFASSetLevels - Sets the number of levels to use with FAS.
65ab8d36c9SPeter Brune    Must be called before any other FAS routine.
66ab8d36c9SPeter Brune 
67ab8d36c9SPeter Brune    Input Parameters:
68ab8d36c9SPeter Brune +  snes   - the snes context
69ab8d36c9SPeter Brune .  levels - the number of levels
70ab8d36c9SPeter Brune -  comms  - optional communicators for each level; this is to allow solving the coarser
712bf68e3eSBarry Smith             problems on smaller sets of processors.
72ab8d36c9SPeter Brune 
73ab8d36c9SPeter Brune    Level: intermediate
74ab8d36c9SPeter Brune 
75ab8d36c9SPeter Brune    Notes:
76ab8d36c9SPeter Brune      If the number of levels is one then the multigrid uses the -fas_levels prefix
77ab8d36c9SPeter Brune   for setting the level options rather than the -fas_coarse prefix.
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];
87f833ba53SLisandro Dalcin   SNES_FAS       *fas;
88ab8d36c9SPeter Brune   SNES           prevsnes;
89ab8d36c9SPeter Brune   MPI_Comm       comm;
9022d28d08SBarry Smith 
91ab8d36c9SPeter Brune   PetscFunctionBegin;
92f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
93f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
94ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
95ab8d36c9SPeter Brune   if (levels == fas->levels) {
9622d28d08SBarry Smith     if (!comms) PetscFunctionReturn(0);
97ab8d36c9SPeter Brune   }
98ab8d36c9SPeter Brune   /* user has changed the number of levels; reset */
99f833ba53SLisandro Dalcin   ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
100ab8d36c9SPeter Brune   /* destroy any coarser levels if necessary */
101f833ba53SLisandro Dalcin   ierr = SNESDestroy(&fas->next);CHKERRQ(ierr);
1020298fd71SBarry Smith   fas->next     = NULL;
1030298fd71SBarry Smith   fas->previous = NULL;
104ab8d36c9SPeter Brune   prevsnes      = snes;
105ab8d36c9SPeter Brune   /* setup the finest level */
106ab8d36c9SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
107ab83eea4SMatthew G. Knepley   ierr = PetscObjectComposedDataSetInt((PetscObject) snes, PetscMGLevelId, levels-1);CHKERRQ(ierr);
108ab8d36c9SPeter Brune   for (i = levels - 1; i >= 0; i--) {
109ab8d36c9SPeter Brune     if (comms) comm = comms[i];
110ab8d36c9SPeter Brune     fas->level  = i;
111ab8d36c9SPeter Brune     fas->levels = levels;
112ab8d36c9SPeter Brune     fas->fine   = snes;
1130298fd71SBarry Smith     fas->next   = NULL;
114ab8d36c9SPeter Brune     if (i > 0) {
115ab8d36c9SPeter Brune       ierr = SNESCreate(comm, &fas->next);CHKERRQ(ierr);
116e964f0dbSPeter Brune       ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr);
117f833ba53SLisandro Dalcin       ierr = PetscSNPrintf(tprefix,sizeof(tprefix),"fas_levels_%d_cycle_",(int)fas->level);CHKERRQ(ierr);
118ab8d36c9SPeter Brune       ierr = SNESAppendOptionsPrefix(fas->next,optionsprefix);CHKERRQ(ierr);
119e964f0dbSPeter Brune       ierr = SNESAppendOptionsPrefix(fas->next,tprefix);CHKERRQ(ierr);
120ab8d36c9SPeter Brune       ierr = SNESSetType(fas->next, SNESFAS);CHKERRQ(ierr);
121ab8d36c9SPeter Brune       ierr = SNESSetTolerances(fas->next, fas->next->abstol, fas->next->rtol, fas->next->stol, fas->n_cycles, fas->next->max_funcs);CHKERRQ(ierr);
122ab8d36c9SPeter Brune       ierr = PetscObjectIncrementTabLevel((PetscObject)fas->next, (PetscObject)snes, levels - i);CHKERRQ(ierr);
123ab83eea4SMatthew G. Knepley       ierr = PetscObjectComposedDataSetInt((PetscObject) fas->next, PetscMGLevelId, i-1);CHKERRQ(ierr);
1241aa26658SKarl Rupp 
125ab8d36c9SPeter Brune       ((SNES_FAS*)fas->next->data)->previous = prevsnes;
1261aa26658SKarl Rupp 
127ab8d36c9SPeter Brune       prevsnes = fas->next;
128ab8d36c9SPeter Brune       fas      = (SNES_FAS*)prevsnes->data;
129ab8d36c9SPeter Brune     }
130ab8d36c9SPeter Brune   }
131ab8d36c9SPeter Brune   PetscFunctionReturn(0);
132ab8d36c9SPeter Brune }
133ab8d36c9SPeter Brune 
134ab8d36c9SPeter Brune 
135ab8d36c9SPeter Brune /*@
136ab8d36c9SPeter Brune    SNESFASGetLevels - Gets the number of levels in a FAS, including fine and coarse grids
137ab8d36c9SPeter Brune 
138ab8d36c9SPeter Brune    Input Parameter:
139ab8d36c9SPeter Brune .  snes - the nonlinear solver context
140ab8d36c9SPeter Brune 
141ab8d36c9SPeter Brune    Output parameter:
142ab8d36c9SPeter Brune .  levels - the number of levels
143ab8d36c9SPeter Brune 
144ab8d36c9SPeter Brune    Level: advanced
145ab8d36c9SPeter Brune 
146ab8d36c9SPeter Brune .seealso: SNESFASSetLevels(), PCMGGetLevels()
147ab8d36c9SPeter Brune @*/
14822d28d08SBarry Smith PetscErrorCode SNESFASGetLevels(SNES snes, PetscInt *levels)
14922d28d08SBarry Smith {
150f833ba53SLisandro Dalcin   SNES_FAS *fas;
1515fd66863SKarl Rupp 
152ab8d36c9SPeter Brune   PetscFunctionBegin;
153f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
154f833ba53SLisandro Dalcin   PetscValidIntPointer(levels,3);
155f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
156ab8d36c9SPeter Brune   *levels = fas->levels;
157ab8d36c9SPeter Brune   PetscFunctionReturn(0);
158ab8d36c9SPeter Brune }
159ab8d36c9SPeter Brune 
160ab8d36c9SPeter Brune 
161ab8d36c9SPeter Brune /*@
162ab8d36c9SPeter Brune    SNESFASGetCycleSNES - Gets the SNES corresponding to a particular
163ab8d36c9SPeter Brune    level of the FAS hierarchy.
164ab8d36c9SPeter Brune 
165ab8d36c9SPeter Brune    Input Parameters:
166ab8d36c9SPeter Brune +  snes    - the multigrid context
167ab8d36c9SPeter Brune    level   - the level to get
168ab8d36c9SPeter Brune -  lsnes   - whether to use the nonlinear smoother or not
169ab8d36c9SPeter Brune 
170ab8d36c9SPeter Brune    Level: advanced
171ab8d36c9SPeter Brune 
172ab8d36c9SPeter Brune .seealso: SNESFASSetLevels(), SNESFASGetLevels()
173ab8d36c9SPeter Brune @*/
17422d28d08SBarry Smith PetscErrorCode SNESFASGetCycleSNES(SNES snes,PetscInt level,SNES *lsnes)
17522d28d08SBarry Smith {
176f833ba53SLisandro Dalcin   SNES_FAS *fas;
177ab8d36c9SPeter Brune   PetscInt i;
178ab8d36c9SPeter Brune 
179ab8d36c9SPeter Brune   PetscFunctionBegin;
180f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
181f833ba53SLisandro Dalcin   PetscValidPointer(lsnes,3);
182f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
183ce94432eSBarry 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);
184ce94432eSBarry 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);
185ab8d36c9SPeter Brune 
186ab8d36c9SPeter Brune   *lsnes = snes;
187ab8d36c9SPeter Brune   for (i = fas->level; i > level; i--) {
188ab8d36c9SPeter Brune     *lsnes = fas->next;
189ab8d36c9SPeter Brune     fas    = (SNES_FAS*)(*lsnes)->data;
190ab8d36c9SPeter Brune   }
191ce94432eSBarry Smith   if (fas->level != level) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"SNESFAS level hierarchy corrupt");
192ab8d36c9SPeter Brune   PetscFunctionReturn(0);
193ab8d36c9SPeter Brune }
194ab8d36c9SPeter Brune 
195ab8d36c9SPeter Brune /*@
196ab8d36c9SPeter Brune    SNESFASSetNumberSmoothUp - Sets the number of post-smoothing steps to
197ab8d36c9SPeter Brune    use on all levels.
198ab8d36c9SPeter Brune 
199ab8d36c9SPeter Brune    Logically Collective on SNES
200ab8d36c9SPeter Brune 
201ab8d36c9SPeter Brune    Input Parameters:
202ab8d36c9SPeter Brune +  snes - the multigrid context
203ab8d36c9SPeter Brune -  n    - the number of smoothing steps
204ab8d36c9SPeter Brune 
205ab8d36c9SPeter Brune    Options Database Key:
206ab8d36c9SPeter Brune .  -snes_fas_smoothup <n> - Sets number of pre-smoothing steps
207ab8d36c9SPeter Brune 
208ab8d36c9SPeter Brune    Level: advanced
209ab8d36c9SPeter Brune 
210ab8d36c9SPeter Brune .seealso: SNESFASSetNumberSmoothDown()
211ab8d36c9SPeter Brune @*/
21222d28d08SBarry Smith PetscErrorCode SNESFASSetNumberSmoothUp(SNES snes, PetscInt n)
21322d28d08SBarry Smith {
214f833ba53SLisandro Dalcin   SNES_FAS       *fas;
21522d28d08SBarry Smith   PetscErrorCode ierr;
21622d28d08SBarry Smith 
217ab8d36c9SPeter Brune   PetscFunctionBegin;
218f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
219f833ba53SLisandro Dalcin   fas =  (SNES_FAS*)snes->data;
220ab8d36c9SPeter Brune   fas->max_up_it = n;
221656ede7eSPeter Brune   if (!fas->smoothu && fas->level != 0) {
22222d28d08SBarry Smith     ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);CHKERRQ(ierr);
223ab8d36c9SPeter Brune   }
22422d28d08SBarry Smith   if (fas->smoothu) {
22522d28d08SBarry Smith     ierr = SNESSetTolerances(fas->smoothu, fas->smoothu->abstol, fas->smoothu->rtol, fas->smoothu->stol, n, fas->smoothu->max_funcs);CHKERRQ(ierr);
22622d28d08SBarry Smith   }
227ab8d36c9SPeter Brune   if (fas->next) {
228ab8d36c9SPeter Brune     ierr = SNESFASSetNumberSmoothUp(fas->next, n);CHKERRQ(ierr);
229ab8d36c9SPeter Brune   }
230ab8d36c9SPeter Brune   PetscFunctionReturn(0);
231ab8d36c9SPeter Brune }
232ab8d36c9SPeter Brune 
233ab8d36c9SPeter Brune /*@
234ab8d36c9SPeter Brune    SNESFASSetNumberSmoothDown - Sets the number of pre-smoothing steps to
235ab8d36c9SPeter Brune    use on all levels.
236ab8d36c9SPeter Brune 
237ab8d36c9SPeter Brune    Logically Collective on SNES
238ab8d36c9SPeter Brune 
239ab8d36c9SPeter Brune    Input Parameters:
240ab8d36c9SPeter Brune +  snes - the multigrid context
241ab8d36c9SPeter Brune -  n    - the number of smoothing steps
242ab8d36c9SPeter Brune 
243ab8d36c9SPeter Brune    Options Database Key:
244ab8d36c9SPeter Brune .  -snes_fas_smoothdown <n> - Sets number of pre-smoothing steps
245ab8d36c9SPeter Brune 
246ab8d36c9SPeter Brune    Level: advanced
247ab8d36c9SPeter Brune 
248ab8d36c9SPeter Brune .seealso: SNESFASSetNumberSmoothUp()
249ab8d36c9SPeter Brune @*/
25022d28d08SBarry Smith PetscErrorCode SNESFASSetNumberSmoothDown(SNES snes, PetscInt n)
25122d28d08SBarry Smith {
252f833ba53SLisandro Dalcin   SNES_FAS       *fas;
253f833ba53SLisandro Dalcin   PetscErrorCode ierr;
25422d28d08SBarry Smith 
255ab8d36c9SPeter Brune   PetscFunctionBegin;
256f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
257f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
258ab8d36c9SPeter Brune   if (!fas->smoothd) {
25922d28d08SBarry Smith     ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);CHKERRQ(ierr);
260ab8d36c9SPeter Brune   }
261ab8d36c9SPeter Brune   ierr = SNESSetTolerances(fas->smoothd, fas->smoothd->abstol, fas->smoothd->rtol, fas->smoothd->stol, n, fas->smoothd->max_funcs);CHKERRQ(ierr);
2621aa26658SKarl Rupp 
263ab8d36c9SPeter Brune   fas->max_down_it = n;
264ab8d36c9SPeter Brune   if (fas->next) {
265ab8d36c9SPeter Brune     ierr = SNESFASSetNumberSmoothDown(fas->next, n);CHKERRQ(ierr);
266ab8d36c9SPeter Brune   }
267ab8d36c9SPeter Brune   PetscFunctionReturn(0);
268ab8d36c9SPeter Brune }
269ab8d36c9SPeter Brune 
270ab8d36c9SPeter Brune 
27187f44e3fSPeter Brune /*@
27287f44e3fSPeter Brune    SNESFASSetContinuation - Sets the FAS cycle to default to exact Newton solves on the upsweep
27387f44e3fSPeter Brune 
27487f44e3fSPeter Brune    Logically Collective on SNES
27587f44e3fSPeter Brune 
27687f44e3fSPeter Brune    Input Parameters:
27787f44e3fSPeter Brune +  snes - the multigrid context
27887f44e3fSPeter Brune -  n    - the number of smoothing steps
27987f44e3fSPeter Brune 
28087f44e3fSPeter Brune    Options Database Key:
28187f44e3fSPeter Brune .  -snes_fas_continuation - sets continuation to true
28287f44e3fSPeter Brune 
28387f44e3fSPeter Brune    Level: advanced
28487f44e3fSPeter Brune 
28595452b02SPatrick Sanan    Notes:
28695452b02SPatrick Sanan     This sets the prefix on the upsweep smoothers to -fas_continuation
28787f44e3fSPeter Brune 
28887f44e3fSPeter Brune .seealso: SNESFAS
28987f44e3fSPeter Brune @*/
29087f44e3fSPeter Brune PetscErrorCode SNESFASSetContinuation(SNES snes,PetscBool continuation)
29187f44e3fSPeter Brune {
29287f44e3fSPeter Brune   const char     *optionsprefix;
29387f44e3fSPeter Brune   char           tprefix[128];
294f833ba53SLisandro Dalcin   SNES_FAS       *fas;
295f833ba53SLisandro Dalcin   PetscErrorCode ierr;
29687f44e3fSPeter Brune 
29787f44e3fSPeter Brune   PetscFunctionBegin;
298f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
299f833ba53SLisandro Dalcin   fas  = (SNES_FAS*)snes->data;
30087f44e3fSPeter Brune   ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr);
30187f44e3fSPeter Brune   if (!fas->smoothu) {
30287f44e3fSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);CHKERRQ(ierr);
30387f44e3fSPeter Brune   }
304f833ba53SLisandro Dalcin   ierr = PetscStrncpy(tprefix,"fas_levels_continuation_",sizeof(tprefix));CHKERRQ(ierr);
30587f44e3fSPeter Brune   ierr = SNESSetOptionsPrefix(fas->smoothu, optionsprefix);CHKERRQ(ierr);
30687f44e3fSPeter Brune   ierr = SNESAppendOptionsPrefix(fas->smoothu, tprefix);CHKERRQ(ierr);
30787f44e3fSPeter Brune   ierr = SNESSetType(fas->smoothu,SNESNEWTONLS);CHKERRQ(ierr);
30887f44e3fSPeter Brune   ierr = SNESSetTolerances(fas->smoothu,fas->fine->abstol,fas->fine->rtol,fas->fine->stol,50,100);CHKERRQ(ierr);
30987f44e3fSPeter Brune   fas->continuation = continuation;
31087f44e3fSPeter Brune   if (fas->next) {
31187f44e3fSPeter Brune     ierr = SNESFASSetContinuation(fas->next,continuation);CHKERRQ(ierr);
31287f44e3fSPeter Brune   }
31387f44e3fSPeter Brune   PetscFunctionReturn(0);
31487f44e3fSPeter Brune }
31587f44e3fSPeter Brune 
31687f44e3fSPeter Brune 
317ab8d36c9SPeter Brune /*@
318ab8d36c9SPeter Brune    SNESFASSetCycles - Sets the number of FAS multigrid cycles to use each time a grid is visited.  Use SNESFASSetCyclesOnLevel() for more
319ab8d36c9SPeter Brune    complicated cycling.
320ab8d36c9SPeter Brune 
321ab8d36c9SPeter Brune    Logically Collective on SNES
322ab8d36c9SPeter Brune 
323ab8d36c9SPeter Brune    Input Parameters:
324ab8d36c9SPeter Brune +  snes   - the multigrid context
325ab8d36c9SPeter Brune -  cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle
326ab8d36c9SPeter Brune 
327ab8d36c9SPeter Brune    Options Database Key:
328e1bc860dSBarry Smith .  -snes_fas_cycles 1 or 2
329ab8d36c9SPeter Brune 
330ab8d36c9SPeter Brune    Level: advanced
331ab8d36c9SPeter Brune 
332ab8d36c9SPeter Brune .seealso: SNESFASSetCyclesOnLevel()
333ab8d36c9SPeter Brune @*/
33422d28d08SBarry Smith PetscErrorCode SNESFASSetCycles(SNES snes, PetscInt cycles)
33522d28d08SBarry Smith {
336f833ba53SLisandro Dalcin   SNES_FAS       *fas;
337ab8d36c9SPeter Brune   PetscErrorCode ierr;
338ab8d36c9SPeter Brune   PetscBool      isFine;
33922d28d08SBarry Smith 
340ab8d36c9SPeter Brune   PetscFunctionBegin;
341f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
34222d28d08SBarry Smith   ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr);
343f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
344ab8d36c9SPeter Brune   fas->n_cycles = cycles;
3451aa26658SKarl Rupp   if (!isFine) {
346ab8d36c9SPeter Brune     ierr = SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);CHKERRQ(ierr);
3471aa26658SKarl Rupp   }
348ab8d36c9SPeter Brune   if (fas->next) {
349ab8d36c9SPeter Brune     ierr = SNESFASSetCycles(fas->next, cycles);CHKERRQ(ierr);
350ab8d36c9SPeter Brune   }
351ab8d36c9SPeter Brune   PetscFunctionReturn(0);
352ab8d36c9SPeter Brune }
353ab8d36c9SPeter Brune 
354c8c899caSPeter Brune 
355c8c899caSPeter Brune /*@
356c8c899caSPeter Brune    SNESFASSetMonitor - Sets the method-specific cycle monitoring
357c8c899caSPeter Brune 
358c8c899caSPeter Brune    Logically Collective on SNES
359c8c899caSPeter Brune 
360c8c899caSPeter Brune    Input Parameters:
361c8c899caSPeter Brune +  snes   - the FAS context
362d142ab34SLawrence Mitchell .  vf     - viewer and format structure (may be NULL if flg is FALSE)
363c8c899caSPeter Brune -  flg    - monitor or not
364c8c899caSPeter Brune 
365c8c899caSPeter Brune    Level: advanced
366c8c899caSPeter Brune 
367c8c899caSPeter Brune .seealso: SNESFASSetCyclesOnLevel()
368c8c899caSPeter Brune @*/
369d142ab34SLawrence Mitchell PetscErrorCode SNESFASSetMonitor(SNES snes, PetscViewerAndFormat *vf, PetscBool flg)
37022d28d08SBarry Smith {
371f833ba53SLisandro Dalcin   SNES_FAS       *fas;
372c8c899caSPeter Brune   PetscErrorCode ierr;
373c8c899caSPeter Brune   PetscBool      isFine;
374f833ba53SLisandro Dalcin   PetscInt       i, levels;
375c8c899caSPeter Brune   SNES           levelsnes;
37622d28d08SBarry Smith 
377c8c899caSPeter Brune   PetscFunctionBegin;
378f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
379c8c899caSPeter Brune   ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr);
380f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
381f833ba53SLisandro Dalcin   levels = fas->levels;
382c8c899caSPeter Brune   if (isFine) {
383c8c899caSPeter Brune     for (i = 0; i < levels; i++) {
38422d28d08SBarry Smith       ierr = SNESFASGetCycleSNES(snes, i, &levelsnes);CHKERRQ(ierr);
385c8c899caSPeter Brune       fas  = (SNES_FAS*)levelsnes->data;
386c8c899caSPeter Brune       if (flg) {
387c8c899caSPeter Brune         /* set the monitors for the upsmoother and downsmoother */
388c8c899caSPeter Brune         ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr);
389d142ab34SLawrence Mitchell         /* Only register destroy on finest level */
390d142ab34SLawrence Mitchell         ierr = SNESMonitorSet(levelsnes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorDefault,vf,(!i ? (PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy : NULL));CHKERRQ(ierr);
3911aa26658SKarl Rupp       } else if (i != fas->levels - 1) {
392c8c899caSPeter Brune         /* unset the monitors on the coarse levels */
393c8c899caSPeter Brune         ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr);
394c8c899caSPeter Brune       }
395c8c899caSPeter Brune     }
396c8c899caSPeter Brune   }
397c8c899caSPeter Brune   PetscFunctionReturn(0);
398c8c899caSPeter Brune }
399c8c899caSPeter Brune 
4000dd27c6cSPeter Brune /*@
4010dd27c6cSPeter Brune    SNESFASSetLog - Sets or unsets time logging for various FAS stages on all levels
4020dd27c6cSPeter Brune 
4030dd27c6cSPeter Brune    Logically Collective on SNES
4040dd27c6cSPeter Brune 
4050dd27c6cSPeter Brune    Input Parameters:
4060dd27c6cSPeter Brune +  snes   - the FAS context
4070dd27c6cSPeter Brune -  flg    - monitor or not
4080dd27c6cSPeter Brune 
4090dd27c6cSPeter Brune    Level: advanced
4100dd27c6cSPeter Brune 
4110dd27c6cSPeter Brune .seealso: SNESFASSetMonitor()
4120dd27c6cSPeter Brune @*/
4130dd27c6cSPeter Brune PetscErrorCode SNESFASSetLog(SNES snes, PetscBool flg)
4140dd27c6cSPeter Brune {
415f833ba53SLisandro Dalcin   SNES_FAS       *fas;
4160dd27c6cSPeter Brune   PetscErrorCode ierr;
4170dd27c6cSPeter Brune   PetscBool      isFine;
418f833ba53SLisandro Dalcin   PetscInt       i, levels;
4190dd27c6cSPeter Brune   SNES           levelsnes;
4200dd27c6cSPeter Brune   char           eventname[128];
4210dd27c6cSPeter Brune 
4220dd27c6cSPeter Brune   PetscFunctionBegin;
423f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
4240dd27c6cSPeter Brune   ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr);
425f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
426f833ba53SLisandro Dalcin   levels = fas->levels;
4270dd27c6cSPeter Brune   if (isFine) {
4280dd27c6cSPeter Brune     for (i = 0; i < levels; i++) {
4290dd27c6cSPeter Brune       ierr = SNESFASGetCycleSNES(snes, i, &levelsnes);CHKERRQ(ierr);
4300dd27c6cSPeter Brune       fas  = (SNES_FAS*)levelsnes->data;
4310dd27c6cSPeter Brune       if (flg) {
432f833ba53SLisandro Dalcin         ierr = PetscSNPrintf(eventname,sizeof(eventname),"FASSetup  %d",(int)i);CHKERRQ(ierr);
4330dd27c6cSPeter Brune         ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsetup);CHKERRQ(ierr);
434f833ba53SLisandro Dalcin         ierr = PetscSNPrintf(eventname,sizeof(eventname),"FASSmooth %d",(int)i);CHKERRQ(ierr);
4350dd27c6cSPeter Brune         ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsolve);CHKERRQ(ierr);
436f833ba53SLisandro Dalcin         ierr = PetscSNPrintf(eventname,sizeof(eventname),"FASResid  %d",(int)i);CHKERRQ(ierr);
4370dd27c6cSPeter Brune         ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventresidual);CHKERRQ(ierr);
438f833ba53SLisandro Dalcin         ierr = PetscSNPrintf(eventname,sizeof(eventname),"FASInterp %d",(int)i);CHKERRQ(ierr);
4390dd27c6cSPeter Brune         ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventinterprestrict);CHKERRQ(ierr);
4400dd27c6cSPeter Brune       } else {
4410298fd71SBarry Smith         fas->eventsmoothsetup    = 0;
4420298fd71SBarry Smith         fas->eventsmoothsolve    = 0;
4430298fd71SBarry Smith         fas->eventresidual       = 0;
4440298fd71SBarry Smith         fas->eventinterprestrict = 0;
4450dd27c6cSPeter Brune       }
4460dd27c6cSPeter Brune     }
4470dd27c6cSPeter Brune   }
4480dd27c6cSPeter Brune   PetscFunctionReturn(0);
4490dd27c6cSPeter Brune }
4500dd27c6cSPeter Brune 
451ab8d36c9SPeter Brune /*
452ab8d36c9SPeter Brune Creates the default smoother type.
453ab8d36c9SPeter Brune 
45404d7464bSBarry Smith This is SNESNRICHARDSON on each fine level and SNESNEWTONLS on the coarse level.
455ab8d36c9SPeter Brune 
456ab8d36c9SPeter Brune  */
45722d28d08SBarry Smith PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES snes, SNES *smooth)
45822d28d08SBarry Smith {
459ab8d36c9SPeter Brune   SNES_FAS       *fas;
460ab8d36c9SPeter Brune   const char     *optionsprefix;
461ab8d36c9SPeter Brune   char           tprefix[128];
462ab8d36c9SPeter Brune   PetscErrorCode ierr;
463ab8d36c9SPeter Brune   SNES           nsmooth;
46422d28d08SBarry Smith 
465ab8d36c9SPeter Brune   PetscFunctionBegin;
466f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
467f833ba53SLisandro Dalcin   PetscValidPointer(smooth,3);
468ab8d36c9SPeter Brune   fas  = (SNES_FAS*)snes->data;
469ab8d36c9SPeter Brune   ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr);
470ab8d36c9SPeter Brune   /* create the default smoother */
471ce94432eSBarry Smith   ierr = SNESCreate(PetscObjectComm((PetscObject)snes), &nsmooth);CHKERRQ(ierr);
472ab8d36c9SPeter Brune   if (fas->level == 0) {
473f833ba53SLisandro Dalcin     ierr = PetscStrncpy(tprefix,"fas_coarse_",sizeof(tprefix));CHKERRQ(ierr);
474ab8d36c9SPeter Brune     ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr);
475ab8d36c9SPeter Brune     ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr);
47604d7464bSBarry Smith     ierr = SNESSetType(nsmooth, SNESNEWTONLS);CHKERRQ(ierr);
477e70c42e5SPeter Brune     ierr = SNESSetTolerances(nsmooth, nsmooth->abstol, nsmooth->rtol, nsmooth->stol, nsmooth->max_its, nsmooth->max_funcs);CHKERRQ(ierr);
478ab8d36c9SPeter Brune   } else {
479f833ba53SLisandro Dalcin     ierr = PetscSNPrintf(tprefix,sizeof(tprefix),"fas_levels_%d_",(int)fas->level);CHKERRQ(ierr);
480ab8d36c9SPeter Brune     ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr);
481ab8d36c9SPeter Brune     ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr);
482ab8d36c9SPeter Brune     ierr = SNESSetType(nsmooth, SNESNRICHARDSON);CHKERRQ(ierr);
483e70c42e5SPeter Brune     ierr = SNESSetTolerances(nsmooth, 0.0, 0.0, 0.0, fas->max_down_it, nsmooth->max_funcs);CHKERRQ(ierr);
484ab8d36c9SPeter Brune   }
485ab8d36c9SPeter Brune   ierr    = PetscObjectIncrementTabLevel((PetscObject)nsmooth, (PetscObject)snes, 1);CHKERRQ(ierr);
4863bb1ff40SBarry Smith   ierr    = PetscLogObjectParent((PetscObject)snes,(PetscObject)nsmooth);CHKERRQ(ierr);
487f89ba88eSPeter Brune   ierr    = PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)nsmooth);CHKERRQ(ierr);
488ab83eea4SMatthew G. Knepley   ierr    = PetscObjectComposedDataSetInt((PetscObject) nsmooth, PetscMGLevelId, fas->level);CHKERRQ(ierr);
489ab8d36c9SPeter Brune   *smooth = nsmooth;
490ab8d36c9SPeter Brune   PetscFunctionReturn(0);
491ab8d36c9SPeter Brune }
492ab8d36c9SPeter Brune 
493ab8d36c9SPeter Brune /* ------------- Functions called on a particular level ----------------- */
494ab8d36c9SPeter Brune 
495ab8d36c9SPeter Brune /*@
496ab8d36c9SPeter Brune    SNESFASCycleSetCycles - Sets the number of cycles on a particular level.
497ab8d36c9SPeter Brune 
498ab8d36c9SPeter Brune    Logically Collective on SNES
499ab8d36c9SPeter Brune 
500ab8d36c9SPeter Brune    Input Parameters:
501ab8d36c9SPeter Brune +  snes   - the multigrid context
502ab8d36c9SPeter Brune .  level  - the level to set the number of cycles on
503ab8d36c9SPeter Brune -  cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle
504ab8d36c9SPeter Brune 
505ab8d36c9SPeter Brune    Level: advanced
506ab8d36c9SPeter Brune 
507ab8d36c9SPeter Brune .seealso: SNESFASSetCycles()
508ab8d36c9SPeter Brune @*/
50922d28d08SBarry Smith PetscErrorCode SNESFASCycleSetCycles(SNES snes, PetscInt cycles)
51022d28d08SBarry Smith {
511f833ba53SLisandro Dalcin   SNES_FAS       *fas;
512ab8d36c9SPeter Brune   PetscErrorCode ierr;
51322d28d08SBarry Smith 
514ab8d36c9SPeter Brune   PetscFunctionBegin;
515f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
516f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
517ab8d36c9SPeter Brune   fas->n_cycles = cycles;
518ab8d36c9SPeter Brune   ierr = SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);CHKERRQ(ierr);
519ab8d36c9SPeter Brune   PetscFunctionReturn(0);
520ab8d36c9SPeter Brune }
521ab8d36c9SPeter Brune 
522ab8d36c9SPeter Brune 
523ab8d36c9SPeter Brune /*@
524ab8d36c9SPeter Brune    SNESFASCycleGetSmoother - Gets the smoother on a particular cycle level.
525ab8d36c9SPeter Brune 
526ab8d36c9SPeter Brune    Logically Collective on SNES
527ab8d36c9SPeter Brune 
528ab8d36c9SPeter Brune    Input Parameters:
529ab8d36c9SPeter Brune .  snes   - the multigrid context
530ab8d36c9SPeter Brune 
531ab8d36c9SPeter Brune    Output Parameters:
532ab8d36c9SPeter Brune .  smooth - the smoother
533ab8d36c9SPeter Brune 
534ab8d36c9SPeter Brune    Level: advanced
535ab8d36c9SPeter Brune 
536ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmootherDown()
537ab8d36c9SPeter Brune @*/
538ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetSmoother(SNES snes, SNES *smooth)
539ab8d36c9SPeter Brune {
540ab8d36c9SPeter Brune   SNES_FAS *fas;
5415fd66863SKarl Rupp 
542ab8d36c9SPeter Brune   PetscFunctionBegin;
543f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
544f833ba53SLisandro Dalcin   PetscValidPointer(smooth,2);
545ab8d36c9SPeter Brune   fas     = (SNES_FAS*)snes->data;
546ab8d36c9SPeter Brune   *smooth = fas->smoothd;
547ab8d36c9SPeter Brune   PetscFunctionReturn(0);
548ab8d36c9SPeter Brune }
549ab8d36c9SPeter Brune /*@
550ab8d36c9SPeter Brune    SNESFASCycleGetSmootherUp - Gets the up smoother on a particular cycle level.
551ab8d36c9SPeter Brune 
552ab8d36c9SPeter Brune    Logically Collective on SNES
553ab8d36c9SPeter Brune 
554ab8d36c9SPeter Brune    Input Parameters:
555ab8d36c9SPeter Brune .  snes   - the multigrid context
556ab8d36c9SPeter Brune 
557ab8d36c9SPeter Brune    Output Parameters:
558ab8d36c9SPeter Brune .  smoothu - the smoother
559ab8d36c9SPeter Brune 
560ab8d36c9SPeter Brune    Notes:
561ab8d36c9SPeter Brune    Returns the downsmoother if no up smoother is available.  This enables transparent
562ab8d36c9SPeter Brune    default behavior in the process of the solve.
563ab8d36c9SPeter Brune 
564ab8d36c9SPeter Brune    Level: advanced
565ab8d36c9SPeter Brune 
566ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmoother(), SNESFASCycleGetSmootherDown()
567ab8d36c9SPeter Brune @*/
568ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetSmootherUp(SNES snes, SNES *smoothu)
569ab8d36c9SPeter Brune {
570ab8d36c9SPeter Brune   SNES_FAS *fas;
5715fd66863SKarl Rupp 
572ab8d36c9SPeter Brune   PetscFunctionBegin;
573f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
574f833ba53SLisandro Dalcin   PetscValidPointer(smoothu,2);
575ab8d36c9SPeter Brune   fas = (SNES_FAS*)snes->data;
5761aa26658SKarl Rupp   if (!fas->smoothu) *smoothu = fas->smoothd;
5771aa26658SKarl Rupp   else *smoothu = fas->smoothu;
578ab8d36c9SPeter Brune   PetscFunctionReturn(0);
579ab8d36c9SPeter Brune }
580ab8d36c9SPeter Brune 
581ab8d36c9SPeter Brune /*@
582ab8d36c9SPeter Brune    SNESFASCycleGetSmootherDown - Gets the down smoother on a particular cycle level.
583ab8d36c9SPeter Brune 
584ab8d36c9SPeter Brune    Logically Collective on SNES
585ab8d36c9SPeter Brune 
586ab8d36c9SPeter Brune    Input Parameters:
587ab8d36c9SPeter Brune .  snes   - the multigrid context
588ab8d36c9SPeter Brune 
589ab8d36c9SPeter Brune    Output Parameters:
590ab8d36c9SPeter Brune .  smoothd - the smoother
591ab8d36c9SPeter Brune 
592ab8d36c9SPeter Brune    Level: advanced
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;
601f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
602f833ba53SLisandro Dalcin   PetscValidPointer(smoothd,2);
603ab8d36c9SPeter Brune   fas = (SNES_FAS*)snes->data;
604ab8d36c9SPeter Brune   *smoothd = fas->smoothd;
605ab8d36c9SPeter Brune   PetscFunctionReturn(0);
606ab8d36c9SPeter Brune }
607ab8d36c9SPeter Brune 
608ab8d36c9SPeter Brune 
609ab8d36c9SPeter Brune /*@
610ab8d36c9SPeter Brune    SNESFASCycleGetCorrection - Gets the coarse correction FAS context for this level
611ab8d36c9SPeter Brune 
612ab8d36c9SPeter Brune    Logically Collective on SNES
613ab8d36c9SPeter Brune 
614ab8d36c9SPeter Brune    Input Parameters:
615ab8d36c9SPeter Brune .  snes   - the multigrid context
616ab8d36c9SPeter Brune 
617ab8d36c9SPeter Brune    Output Parameters:
618ab8d36c9SPeter Brune .  correction - the coarse correction on this level
619ab8d36c9SPeter Brune 
620ab8d36c9SPeter Brune    Notes:
6210298fd71SBarry Smith    Returns NULL on the coarsest level.
622ab8d36c9SPeter Brune 
623ab8d36c9SPeter Brune    Level: advanced
624ab8d36c9SPeter Brune 
625ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
626ab8d36c9SPeter Brune @*/
627ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetCorrection(SNES snes, SNES *correction)
628ab8d36c9SPeter Brune {
629ab8d36c9SPeter Brune   SNES_FAS *fas;
6305fd66863SKarl Rupp 
631ab8d36c9SPeter Brune   PetscFunctionBegin;
632f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
633f833ba53SLisandro Dalcin   PetscValidPointer(correction,2);
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 .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother()
653ab8d36c9SPeter Brune @*/
654ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetInterpolation(SNES snes, Mat *mat)
655ab8d36c9SPeter Brune {
656ab8d36c9SPeter Brune   SNES_FAS *fas;
6575fd66863SKarl Rupp 
658ab8d36c9SPeter Brune   PetscFunctionBegin;
659f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
660f833ba53SLisandro Dalcin   PetscValidPointer(mat,2);
661ab8d36c9SPeter Brune   fas = (SNES_FAS*)snes->data;
662ab8d36c9SPeter Brune   *mat = fas->interpolate;
663ab8d36c9SPeter Brune   PetscFunctionReturn(0);
664ab8d36c9SPeter Brune }
665ab8d36c9SPeter Brune 
666ab8d36c9SPeter Brune 
667ab8d36c9SPeter Brune /*@
668ab8d36c9SPeter Brune    SNESFASCycleGetRestriction - Gets the restriction on this level
669ab8d36c9SPeter Brune 
670ab8d36c9SPeter Brune    Logically Collective on SNES
671ab8d36c9SPeter Brune 
672ab8d36c9SPeter Brune    Input Parameters:
673ab8d36c9SPeter Brune .  snes   - the multigrid context
674ab8d36c9SPeter Brune 
675ab8d36c9SPeter Brune    Output Parameters:
676ab8d36c9SPeter Brune .  mat    - the restriction operator on this level
677ab8d36c9SPeter Brune 
678ab8d36c9SPeter Brune    Level: developer
679ab8d36c9SPeter Brune 
680ab8d36c9SPeter Brune .seealso: SNESFASGetRestriction(), SNESFASCycleGetInterpolation()
681ab8d36c9SPeter Brune @*/
682ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetRestriction(SNES snes, Mat *mat)
683ab8d36c9SPeter Brune {
684ab8d36c9SPeter Brune   SNES_FAS *fas;
6855fd66863SKarl Rupp 
686ab8d36c9SPeter Brune   PetscFunctionBegin;
687f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
688f833ba53SLisandro Dalcin   PetscValidPointer(mat,2);
689ab8d36c9SPeter Brune   fas = (SNES_FAS*)snes->data;
690ab8d36c9SPeter Brune   *mat = fas->restrct;
691ab8d36c9SPeter Brune   PetscFunctionReturn(0);
692ab8d36c9SPeter Brune }
693ab8d36c9SPeter Brune 
694ab8d36c9SPeter Brune 
695ab8d36c9SPeter Brune /*@
696ab8d36c9SPeter Brune    SNESFASCycleGetInjection - Gets the injection on this level
697ab8d36c9SPeter Brune 
698ab8d36c9SPeter Brune    Logically Collective on SNES
699ab8d36c9SPeter Brune 
700ab8d36c9SPeter Brune    Input Parameters:
701ab8d36c9SPeter Brune .  snes   - the multigrid context
702ab8d36c9SPeter Brune 
703ab8d36c9SPeter Brune    Output Parameters:
704ab8d36c9SPeter Brune .  mat    - the restriction operator on this level
705ab8d36c9SPeter Brune 
706ab8d36c9SPeter Brune    Level: developer
707ab8d36c9SPeter Brune 
708ab8d36c9SPeter Brune .seealso: SNESFASGetInjection(), SNESFASCycleGetRestriction()
709ab8d36c9SPeter Brune @*/
710ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetInjection(SNES snes, Mat *mat)
711ab8d36c9SPeter Brune {
712ab8d36c9SPeter Brune   SNES_FAS *fas;
7135fd66863SKarl Rupp 
714ab8d36c9SPeter Brune   PetscFunctionBegin;
715f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
716f833ba53SLisandro Dalcin   PetscValidPointer(mat,2);
717ab8d36c9SPeter Brune   fas = (SNES_FAS*)snes->data;
718ab8d36c9SPeter Brune   *mat = fas->inject;
719ab8d36c9SPeter Brune   PetscFunctionReturn(0);
720ab8d36c9SPeter Brune }
721ab8d36c9SPeter Brune 
722ab8d36c9SPeter Brune /*@
723ab8d36c9SPeter Brune    SNESFASCycleGetRScale - Gets the injection on this level
724ab8d36c9SPeter Brune 
725ab8d36c9SPeter Brune    Logically Collective on SNES
726ab8d36c9SPeter Brune 
727ab8d36c9SPeter Brune    Input Parameters:
728ab8d36c9SPeter Brune .  snes   - the multigrid context
729ab8d36c9SPeter Brune 
730ab8d36c9SPeter Brune    Output Parameters:
731ab8d36c9SPeter Brune .  mat    - the restriction operator on this level
732ab8d36c9SPeter Brune 
733ab8d36c9SPeter Brune    Level: developer
734ab8d36c9SPeter Brune 
735ab8d36c9SPeter Brune .seealso: SNESFASCycleGetRestriction(), SNESFASGetRScale()
736ab8d36c9SPeter Brune @*/
737ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetRScale(SNES snes, Vec *vec)
738ab8d36c9SPeter Brune {
739ab8d36c9SPeter Brune   SNES_FAS *fas;
7405fd66863SKarl Rupp 
741ab8d36c9SPeter Brune   PetscFunctionBegin;
742f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
743f833ba53SLisandro Dalcin   PetscValidPointer(vec,2);
744ab8d36c9SPeter Brune   fas  = (SNES_FAS*)snes->data;
745ab8d36c9SPeter Brune   *vec = fas->rscale;
746ab8d36c9SPeter Brune   PetscFunctionReturn(0);
747ab8d36c9SPeter Brune }
748ab8d36c9SPeter Brune 
749ab8d36c9SPeter Brune /*@
750ab8d36c9SPeter Brune    SNESFASCycleIsFine - Determines if a given cycle is the fine level.
751ab8d36c9SPeter Brune 
752ab8d36c9SPeter Brune    Logically Collective on SNES
753ab8d36c9SPeter Brune 
754ab8d36c9SPeter Brune    Input Parameters:
755ab8d36c9SPeter Brune .  snes   - the FAS context
756ab8d36c9SPeter Brune 
757ab8d36c9SPeter Brune    Output Parameters:
758ab8d36c9SPeter Brune .  flg - indicates if this is the fine level or not
759ab8d36c9SPeter Brune 
760ab8d36c9SPeter Brune    Level: advanced
761ab8d36c9SPeter Brune 
762ab8d36c9SPeter Brune .seealso: SNESFASSetLevels()
763ab8d36c9SPeter Brune @*/
764ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleIsFine(SNES snes, PetscBool *flg)
765ab8d36c9SPeter Brune {
766ab8d36c9SPeter Brune   SNES_FAS *fas;
7675fd66863SKarl Rupp 
768ab8d36c9SPeter Brune   PetscFunctionBegin;
769f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
770*534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
771ab8d36c9SPeter Brune   fas = (SNES_FAS*)snes->data;
7721aa26658SKarl Rupp   if (fas->level == fas->levels - 1) *flg = PETSC_TRUE;
7731aa26658SKarl Rupp   else *flg = PETSC_FALSE;
774ab8d36c9SPeter Brune   PetscFunctionReturn(0);
775ab8d36c9SPeter Brune }
776ab8d36c9SPeter Brune 
777ab8d36c9SPeter Brune /* ---------- functions called on the finest level that return level-specific information ---------- */
778ab8d36c9SPeter Brune 
779ab8d36c9SPeter Brune /*@
780ab8d36c9SPeter Brune    SNESFASSetInterpolation - Sets the function to be used to calculate the
781ab8d36c9SPeter Brune    interpolation from l-1 to the lth level
782ab8d36c9SPeter Brune 
783ab8d36c9SPeter Brune    Input Parameters:
784ab8d36c9SPeter Brune +  snes      - the multigrid context
785ab8d36c9SPeter Brune .  mat       - the interpolation operator
786ab8d36c9SPeter Brune -  level     - the level (0 is coarsest) to supply [do not supply 0]
787ab8d36c9SPeter Brune 
788ab8d36c9SPeter Brune    Level: advanced
789ab8d36c9SPeter Brune 
790ab8d36c9SPeter Brune    Notes:
791ab8d36c9SPeter Brune           Usually this is the same matrix used also to set the restriction
792ab8d36c9SPeter Brune     for the same level.
793ab8d36c9SPeter Brune 
794ab8d36c9SPeter Brune           One can pass in the interpolation matrix or its transpose; PETSc figures
795ab8d36c9SPeter Brune     out from the matrix size which one it is.
796ab8d36c9SPeter Brune 
797ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction(), SNESFASSetRScale()
798ab8d36c9SPeter Brune @*/
7990adebc6cSBarry Smith PetscErrorCode SNESFASSetInterpolation(SNES snes, PetscInt level, Mat mat)
8000adebc6cSBarry Smith {
80122d28d08SBarry Smith   SNES_FAS       *fas;
802ab8d36c9SPeter Brune   PetscErrorCode ierr;
803ab8d36c9SPeter Brune   SNES           levelsnes;
80422d28d08SBarry Smith 
805ab8d36c9SPeter Brune   PetscFunctionBegin;
806f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
807f833ba53SLisandro Dalcin   if (mat) PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
808ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
809ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
810ab8d36c9SPeter Brune   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
811ab8d36c9SPeter Brune   ierr = MatDestroy(&fas->interpolate);CHKERRQ(ierr);
812ab8d36c9SPeter Brune   fas->interpolate = mat;
813ab8d36c9SPeter Brune   PetscFunctionReturn(0);
814ab8d36c9SPeter Brune }
815ab8d36c9SPeter Brune 
816ab8d36c9SPeter Brune /*@
817ab8d36c9SPeter Brune    SNESFASGetInterpolation - Gets the matrix used to calculate the
818ab8d36c9SPeter Brune    interpolation from l-1 to the lth level
819ab8d36c9SPeter Brune 
820ab8d36c9SPeter Brune    Input Parameters:
821ab8d36c9SPeter Brune +  snes      - the multigrid context
822ab8d36c9SPeter Brune -  level     - the level (0 is coarsest) to supply [do not supply 0]
823ab8d36c9SPeter Brune 
824ab8d36c9SPeter Brune    Output Parameters:
825ab8d36c9SPeter Brune .  mat       - the interpolation operator
826ab8d36c9SPeter Brune 
827ab8d36c9SPeter Brune    Level: advanced
828ab8d36c9SPeter Brune 
829ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASGetInjection(), SNESFASGetRestriction(), SNESFASGetRScale()
830ab8d36c9SPeter Brune @*/
83122d28d08SBarry Smith PetscErrorCode SNESFASGetInterpolation(SNES snes, PetscInt level, Mat *mat)
83222d28d08SBarry Smith {
83322d28d08SBarry Smith   SNES_FAS       *fas;
834ab8d36c9SPeter Brune   PetscErrorCode ierr;
835ab8d36c9SPeter Brune   SNES           levelsnes;
83622d28d08SBarry Smith 
837ab8d36c9SPeter Brune   PetscFunctionBegin;
838f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
839f833ba53SLisandro Dalcin   PetscValidPointer(mat,3);
840ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
841ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
842ab8d36c9SPeter Brune   *mat = fas->interpolate;
843ab8d36c9SPeter Brune   PetscFunctionReturn(0);
844ab8d36c9SPeter Brune }
845ab8d36c9SPeter Brune 
846ab8d36c9SPeter Brune /*@
847ab8d36c9SPeter Brune    SNESFASSetRestriction - Sets the function to be used to restrict the defect
848ab8d36c9SPeter Brune    from level l to l-1.
849ab8d36c9SPeter Brune 
850ab8d36c9SPeter Brune    Input Parameters:
851ab8d36c9SPeter Brune +  snes  - the multigrid context
852ab8d36c9SPeter Brune .  mat   - the restriction matrix
853ab8d36c9SPeter Brune -  level - the level (0 is coarsest) to supply [Do not supply 0]
854ab8d36c9SPeter Brune 
855ab8d36c9SPeter Brune    Level: advanced
856ab8d36c9SPeter Brune 
857ab8d36c9SPeter Brune    Notes:
858ab8d36c9SPeter Brune           Usually this is the same matrix used also to set the interpolation
859ab8d36c9SPeter Brune     for the same level.
860ab8d36c9SPeter Brune 
861ab8d36c9SPeter Brune           One can pass in the interpolation matrix or its transpose; PETSc figures
862ab8d36c9SPeter Brune     out from the matrix size which one it is.
863ab8d36c9SPeter Brune 
864ab8d36c9SPeter Brune          If you do not set this, the transpose of the Mat set with SNESFASSetInterpolation()
865ab8d36c9SPeter Brune     is used.
866ab8d36c9SPeter Brune 
867ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASSetInjection()
868ab8d36c9SPeter Brune @*/
86922d28d08SBarry Smith PetscErrorCode SNESFASSetRestriction(SNES snes, PetscInt level, Mat mat)
87022d28d08SBarry Smith {
87122d28d08SBarry Smith   SNES_FAS       *fas;
872ab8d36c9SPeter Brune   PetscErrorCode ierr;
873ab8d36c9SPeter Brune   SNES           levelsnes;
87422d28d08SBarry Smith 
875ab8d36c9SPeter Brune   PetscFunctionBegin;
876f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
877f833ba53SLisandro Dalcin   if (mat) PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
878ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
879ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
880ab8d36c9SPeter Brune   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
881ab8d36c9SPeter Brune   ierr = MatDestroy(&fas->restrct);CHKERRQ(ierr);
882ab8d36c9SPeter Brune   fas->restrct = mat;
883ab8d36c9SPeter Brune   PetscFunctionReturn(0);
884ab8d36c9SPeter Brune }
885ab8d36c9SPeter Brune 
886ab8d36c9SPeter Brune /*@
887ab8d36c9SPeter Brune    SNESFASGetRestriction - Gets the matrix used to calculate the
888ab8d36c9SPeter Brune    restriction from l to the l-1th level
889ab8d36c9SPeter Brune 
890ab8d36c9SPeter Brune    Input Parameters:
891ab8d36c9SPeter Brune +  snes      - the multigrid context
892ab8d36c9SPeter Brune -  level     - the level (0 is coarsest) to supply [do not supply 0]
893ab8d36c9SPeter Brune 
894ab8d36c9SPeter Brune    Output Parameters:
895ab8d36c9SPeter Brune .  mat       - the interpolation operator
896ab8d36c9SPeter Brune 
897ab8d36c9SPeter Brune    Level: advanced
898ab8d36c9SPeter Brune 
899ab8d36c9SPeter Brune .seealso: SNESFASSetRestriction(), SNESFASGetInjection(), SNESFASGetInterpolation(), SNESFASGetRScale()
900ab8d36c9SPeter Brune @*/
90122d28d08SBarry Smith PetscErrorCode SNESFASGetRestriction(SNES snes, PetscInt level, Mat *mat)
90222d28d08SBarry Smith {
90322d28d08SBarry Smith   SNES_FAS       *fas;
904ab8d36c9SPeter Brune   PetscErrorCode ierr;
905ab8d36c9SPeter Brune   SNES           levelsnes;
90622d28d08SBarry Smith 
907ab8d36c9SPeter Brune   PetscFunctionBegin;
908f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
909f833ba53SLisandro Dalcin   PetscValidPointer(mat,3);
910ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
911ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
912ab8d36c9SPeter Brune   *mat = fas->restrct;
913ab8d36c9SPeter Brune   PetscFunctionReturn(0);
914ab8d36c9SPeter Brune }
915ab8d36c9SPeter Brune 
916ab8d36c9SPeter Brune 
917ab8d36c9SPeter Brune /*@
918ab8d36c9SPeter Brune    SNESFASSetInjection - Sets the function to be used to inject the solution
919ab8d36c9SPeter Brune    from level l to l-1.
920ab8d36c9SPeter Brune 
921ab8d36c9SPeter Brune    Input Parameters:
922ab8d36c9SPeter Brune  +  snes  - the multigrid context
923ab8d36c9SPeter Brune .  mat   - the restriction matrix
924ab8d36c9SPeter Brune -  level - the level (0 is coarsest) to supply [Do not supply 0]
925ab8d36c9SPeter Brune 
926ab8d36c9SPeter Brune    Level: advanced
927ab8d36c9SPeter Brune 
928ab8d36c9SPeter Brune    Notes:
929ab8d36c9SPeter Brune          If you do not set this, the restriction and rscale is used to
930ab8d36c9SPeter Brune    project the solution instead.
931ab8d36c9SPeter Brune 
932ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASSetRestriction()
933ab8d36c9SPeter Brune @*/
93422d28d08SBarry Smith PetscErrorCode SNESFASSetInjection(SNES snes, PetscInt level, Mat mat)
93522d28d08SBarry Smith {
93622d28d08SBarry Smith   SNES_FAS       *fas;
937ab8d36c9SPeter Brune   PetscErrorCode ierr;
938ab8d36c9SPeter Brune   SNES           levelsnes;
93922d28d08SBarry Smith 
940ab8d36c9SPeter Brune   PetscFunctionBegin;
941f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
942f833ba53SLisandro Dalcin   if (mat) PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
943ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
944ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
945ab8d36c9SPeter Brune   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
946ab8d36c9SPeter Brune   ierr = MatDestroy(&fas->inject);CHKERRQ(ierr);
9471aa26658SKarl Rupp 
948ab8d36c9SPeter Brune   fas->inject = mat;
949ab8d36c9SPeter Brune   PetscFunctionReturn(0);
950ab8d36c9SPeter Brune }
951ab8d36c9SPeter Brune 
952ab8d36c9SPeter Brune 
953ab8d36c9SPeter Brune /*@
954ab8d36c9SPeter Brune    SNESFASGetInjection - Gets the matrix used to calculate the
955ab8d36c9SPeter Brune    injection from l-1 to the lth level
956ab8d36c9SPeter Brune 
957ab8d36c9SPeter Brune    Input Parameters:
958ab8d36c9SPeter Brune +  snes      - the multigrid context
959ab8d36c9SPeter Brune -  level     - the level (0 is coarsest) to supply [do not supply 0]
960ab8d36c9SPeter Brune 
961ab8d36c9SPeter Brune    Output Parameters:
962ab8d36c9SPeter Brune .  mat       - the injection operator
963ab8d36c9SPeter Brune 
964ab8d36c9SPeter Brune    Level: advanced
965ab8d36c9SPeter Brune 
966ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASGetRestriction(), SNESFASGetInterpolation(), SNESFASGetRScale()
967ab8d36c9SPeter Brune @*/
96822d28d08SBarry Smith PetscErrorCode SNESFASGetInjection(SNES snes, PetscInt level, Mat *mat)
96922d28d08SBarry Smith {
97022d28d08SBarry Smith   SNES_FAS       *fas;
971ab8d36c9SPeter Brune   PetscErrorCode ierr;
972ab8d36c9SPeter Brune   SNES           levelsnes;
97322d28d08SBarry Smith 
974ab8d36c9SPeter Brune   PetscFunctionBegin;
975f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
976f833ba53SLisandro Dalcin   PetscValidPointer(mat,3);
977ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
978ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
979ab8d36c9SPeter Brune   *mat = fas->inject;
980ab8d36c9SPeter Brune   PetscFunctionReturn(0);
981ab8d36c9SPeter Brune }
982ab8d36c9SPeter Brune 
983ab8d36c9SPeter Brune /*@
984ab8d36c9SPeter Brune    SNESFASSetRScale - Sets the scaling factor of the restriction
985ab8d36c9SPeter Brune    operator from level l to l-1.
986ab8d36c9SPeter Brune 
987ab8d36c9SPeter Brune    Input Parameters:
988ab8d36c9SPeter Brune +  snes   - the multigrid context
989ab8d36c9SPeter Brune .  rscale - the restriction scaling
990ab8d36c9SPeter Brune -  level  - the level (0 is coarsest) to supply [Do not supply 0]
991ab8d36c9SPeter Brune 
992ab8d36c9SPeter Brune    Level: advanced
993ab8d36c9SPeter Brune 
994ab8d36c9SPeter Brune    Notes:
995ab8d36c9SPeter Brune          This is only used in the case that the injection is not set.
996ab8d36c9SPeter Brune 
997ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
998ab8d36c9SPeter Brune @*/
99922d28d08SBarry Smith PetscErrorCode SNESFASSetRScale(SNES snes, PetscInt level, Vec rscale)
100022d28d08SBarry Smith {
1001ab8d36c9SPeter Brune   SNES_FAS       *fas;
1002ab8d36c9SPeter Brune   PetscErrorCode ierr;
1003ab8d36c9SPeter Brune   SNES           levelsnes;
100422d28d08SBarry Smith 
1005ab8d36c9SPeter Brune   PetscFunctionBegin;
1006f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
1007f833ba53SLisandro Dalcin   if (rscale) PetscValidHeaderSpecific(rscale,VEC_CLASSID,3);
1008ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
1009ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1010ab8d36c9SPeter Brune   ierr = PetscObjectReference((PetscObject)rscale);CHKERRQ(ierr);
1011ab8d36c9SPeter Brune   ierr = VecDestroy(&fas->rscale);CHKERRQ(ierr);
1012ab8d36c9SPeter Brune   fas->rscale = rscale;
1013ab8d36c9SPeter Brune   PetscFunctionReturn(0);
1014ab8d36c9SPeter Brune }
1015ab8d36c9SPeter Brune 
1016ab8d36c9SPeter Brune /*@
1017ab8d36c9SPeter Brune    SNESFASGetSmoother - Gets the default smoother on a level.
1018ab8d36c9SPeter Brune 
1019ab8d36c9SPeter Brune    Input Parameters:
1020ab8d36c9SPeter Brune +  snes   - the multigrid context
1021ab8d36c9SPeter Brune -  level  - the level (0 is coarsest) to supply
1022ab8d36c9SPeter Brune 
1023ab8d36c9SPeter Brune    Output Parameters:
1024ab8d36c9SPeter Brune    smooth  - the smoother
1025ab8d36c9SPeter Brune 
1026ab8d36c9SPeter Brune    Level: advanced
1027ab8d36c9SPeter Brune 
1028ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1029ab8d36c9SPeter Brune @*/
103022d28d08SBarry Smith PetscErrorCode SNESFASGetSmoother(SNES snes, PetscInt level, SNES *smooth)
103122d28d08SBarry Smith {
1032ab8d36c9SPeter Brune   SNES_FAS       *fas;
1033ab8d36c9SPeter Brune   PetscErrorCode ierr;
1034ab8d36c9SPeter Brune   SNES           levelsnes;
103522d28d08SBarry Smith 
1036ab8d36c9SPeter Brune   PetscFunctionBegin;
1037f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
1038f833ba53SLisandro Dalcin   PetscValidPointer(smooth,3);
1039ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
1040ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1041ab8d36c9SPeter Brune   if (!fas->smoothd) {
10423de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr);
1043ab8d36c9SPeter Brune   }
1044ab8d36c9SPeter Brune   *smooth = fas->smoothd;
1045ab8d36c9SPeter Brune   PetscFunctionReturn(0);
1046ab8d36c9SPeter Brune }
1047ab8d36c9SPeter Brune 
1048ab8d36c9SPeter Brune /*@
1049ab8d36c9SPeter Brune    SNESFASGetSmootherDown - Gets the downsmoother on a level.
1050ab8d36c9SPeter Brune 
1051ab8d36c9SPeter Brune    Input Parameters:
1052ab8d36c9SPeter Brune +  snes   - the multigrid context
1053ab8d36c9SPeter Brune -  level  - the level (0 is coarsest) to supply
1054ab8d36c9SPeter Brune 
1055ab8d36c9SPeter Brune    Output Parameters:
1056ab8d36c9SPeter Brune    smooth  - the smoother
1057ab8d36c9SPeter Brune 
1058ab8d36c9SPeter Brune    Level: advanced
1059ab8d36c9SPeter Brune 
1060ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1061ab8d36c9SPeter Brune @*/
106222d28d08SBarry Smith PetscErrorCode SNESFASGetSmootherDown(SNES snes, PetscInt level, SNES *smooth)
106322d28d08SBarry Smith {
1064ab8d36c9SPeter Brune   SNES_FAS       *fas;
1065ab8d36c9SPeter Brune   PetscErrorCode ierr;
1066ab8d36c9SPeter Brune   SNES           levelsnes;
106722d28d08SBarry Smith 
1068ab8d36c9SPeter Brune   PetscFunctionBegin;
1069f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
1070f833ba53SLisandro Dalcin   PetscValidPointer(smooth,3);
1071ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
1072ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1073ab8d36c9SPeter Brune   /* if the user chooses to differentiate smoothers, create them both at this point */
1074ab8d36c9SPeter Brune   if (!fas->smoothd) {
10753de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr);
1076ab8d36c9SPeter Brune   }
1077ab8d36c9SPeter Brune   if (!fas->smoothu) {
10783de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);CHKERRQ(ierr);
1079ab8d36c9SPeter Brune   }
1080ab8d36c9SPeter Brune   *smooth = fas->smoothd;
1081ab8d36c9SPeter Brune   PetscFunctionReturn(0);
1082ab8d36c9SPeter Brune }
1083ab8d36c9SPeter Brune 
1084ab8d36c9SPeter Brune /*@
1085ab8d36c9SPeter Brune    SNESFASGetSmootherUp - Gets the upsmoother on a level.
1086ab8d36c9SPeter Brune 
1087ab8d36c9SPeter Brune    Input Parameters:
1088ab8d36c9SPeter Brune +  snes   - the multigrid context
1089ab8d36c9SPeter Brune -  level  - the level (0 is coarsest)
1090ab8d36c9SPeter Brune 
1091ab8d36c9SPeter Brune    Output Parameters:
1092ab8d36c9SPeter Brune    smooth  - the smoother
1093ab8d36c9SPeter Brune 
1094ab8d36c9SPeter Brune    Level: advanced
1095ab8d36c9SPeter Brune 
1096ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1097ab8d36c9SPeter Brune @*/
109822d28d08SBarry Smith PetscErrorCode SNESFASGetSmootherUp(SNES snes, PetscInt level, SNES *smooth)
109922d28d08SBarry Smith {
1100ab8d36c9SPeter Brune   SNES_FAS       *fas;
1101ab8d36c9SPeter Brune   PetscErrorCode ierr;
1102ab8d36c9SPeter Brune   SNES           levelsnes;
110322d28d08SBarry Smith 
1104ab8d36c9SPeter Brune   PetscFunctionBegin;
1105f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
1106f833ba53SLisandro Dalcin   PetscValidPointer(smooth,3);
1107ab8d36c9SPeter Brune   ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr);
1108ab8d36c9SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1109ab8d36c9SPeter Brune   /* if the user chooses to differentiate smoothers, create them both at this point */
1110ab8d36c9SPeter Brune   if (!fas->smoothd) {
11113de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr);
1112ab8d36c9SPeter Brune   }
1113ab8d36c9SPeter Brune   if (!fas->smoothu) {
11143de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);CHKERRQ(ierr);
1115ab8d36c9SPeter Brune   }
1116ab8d36c9SPeter Brune   *smooth = fas->smoothu;
1117ab8d36c9SPeter Brune   PetscFunctionReturn(0);
1118ab8d36c9SPeter Brune }
1119d6ad1212SPeter Brune 
1120d6ad1212SPeter Brune /*@
1121d6ad1212SPeter Brune   SNESFASGetCoarseSolve - Gets the coarsest solver.
1122d6ad1212SPeter Brune 
1123d6ad1212SPeter Brune   Input Parameters:
1124a3a80b83SMatthew G. Knepley . snes - the multigrid context
1125d6ad1212SPeter Brune 
1126d6ad1212SPeter Brune   Output Parameters:
1127a3a80b83SMatthew G. Knepley . coarse - the coarse-level solver
1128d6ad1212SPeter Brune 
1129d6ad1212SPeter Brune   Level: advanced
1130d6ad1212SPeter Brune 
1131d6ad1212SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction()
1132d6ad1212SPeter Brune @*/
1133a3a80b83SMatthew G. Knepley PetscErrorCode SNESFASGetCoarseSolve(SNES snes, SNES *coarse)
113422d28d08SBarry Smith {
1135d6ad1212SPeter Brune   SNES_FAS       *fas;
1136d6ad1212SPeter Brune   PetscErrorCode ierr;
1137d6ad1212SPeter Brune   SNES           levelsnes;
113822d28d08SBarry Smith 
1139d6ad1212SPeter Brune   PetscFunctionBegin;
1140f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
1141f833ba53SLisandro Dalcin   PetscValidPointer(coarse,3);
1142d6ad1212SPeter Brune   ierr = SNESFASGetCycleSNES(snes, 0, &levelsnes);CHKERRQ(ierr);
1143d6ad1212SPeter Brune   fas  = (SNES_FAS*)levelsnes->data;
1144d6ad1212SPeter Brune   /* if the user chooses to differentiate smoothers, create them both at this point */
1145d6ad1212SPeter Brune   if (!fas->smoothd) {
11463de4d1dbSPeter Brune     ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr);
1147d6ad1212SPeter Brune   }
1148a3a80b83SMatthew G. Knepley   *coarse = fas->smoothd;
1149d6ad1212SPeter Brune   PetscFunctionReturn(0);
1150d6ad1212SPeter Brune }
1151928e959bSPeter Brune 
1152928e959bSPeter Brune /*@
1153928e959bSPeter Brune    SNESFASFullSetDownSweep - Smooth during the initial downsweep for SNESFAS
1154928e959bSPeter Brune 
1155928e959bSPeter Brune    Logically Collective on SNES
1156928e959bSPeter Brune 
1157928e959bSPeter Brune    Input Parameters:
1158928e959bSPeter Brune +  snes - the multigrid context
1159928e959bSPeter Brune -  swp - whether to downsweep or not
1160928e959bSPeter Brune 
1161928e959bSPeter Brune    Options Database Key:
1162928e959bSPeter Brune .  -snes_fas_full_downsweep - Sets number of pre-smoothing steps
1163928e959bSPeter Brune 
1164928e959bSPeter Brune    Level: advanced
1165928e959bSPeter Brune 
1166928e959bSPeter Brune .seealso: SNESFASSetNumberSmoothUp()
1167928e959bSPeter Brune @*/
1168928e959bSPeter Brune PetscErrorCode SNESFASFullSetDownSweep(SNES snes,PetscBool swp)
1169928e959bSPeter Brune {
1170f833ba53SLisandro Dalcin   SNES_FAS       *fas;
1171f833ba53SLisandro Dalcin   PetscErrorCode ierr;
1172928e959bSPeter Brune 
1173928e959bSPeter Brune   PetscFunctionBegin;
1174f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS);
1175f833ba53SLisandro Dalcin   fas = (SNES_FAS*)snes->data;
1176928e959bSPeter Brune   fas->full_downsweep = swp;
1177928e959bSPeter Brune   if (fas->next) {
1178928e959bSPeter Brune     ierr = SNESFASFullSetDownSweep(fas->next,swp);CHKERRQ(ierr);
1179928e959bSPeter Brune   }
1180928e959bSPeter Brune   PetscFunctionReturn(0);
1181928e959bSPeter Brune }
1182