Actual source code: mgfunc.c
1: /*$Id: mgfunc.c,v 1.41 2001/08/07 03:03:36 balay Exp $*/
3: #include src/sles/pc/impls/mg/mgimpl.h
4: /*I "petscmg.h" I*/
8: /*@C
9: MGDefaultResidual - Default routine to calculate the residual.
11: Collective on Mat and Vec
13: Input Parameters:
14: + mat - the matrix
15: . b - the right-hand-side
16: - x - the approximate solution
17:
18: Output Parameter:
19: . r - location to store the residual
21: Level: advanced
23: .keywords: MG, default, multigrid, residual
25: .seealso: MGSetResidual()
26: @*/
27: int MGDefaultResidual(Mat mat,Vec b,Vec x,Vec r)
28: {
29: int ierr;
30: PetscScalar mone = -1.0;
33: MatMult(mat,x,r);
34: VecAYPX(&mone,b,r);
35: return(0);
36: }
38: /* ---------------------------------------------------------------------------*/
42: /*@C
43: MGGetCoarseSolve - Gets the solver context to be used on the coarse grid.
45: Not Collective
47: Input Parameter:
48: . pc - the multigrid context
50: Output Parameter:
51: . sles - the coarse grid solver context
53: Level: advanced
55: .keywords: MG, multigrid, get, coarse grid
56: @*/
57: int MGGetCoarseSolve(PC pc,SLES *sles)
58: {
59: MG *mg = (MG*)pc->data;
62: *sles = mg[0]->smoothd;
63: return(0);
64: }
68: /*@C
69: MGSetResidual - Sets the function to be used to calculate the residual
70: on the lth level.
72: Collective on PC and Mat
74: Input Parameters:
75: + pc - the multigrid context
76: . l - the level (0 is coarsest) to supply
77: . residual - function used to form residual (usually MGDefaultResidual)
78: - mat - matrix associated with residual
80: Level: advanced
82: .keywords: MG, set, multigrid, residual, level
84: .seealso: MGDefaultResidual()
85: @*/
86: int MGSetResidual(PC pc,int l,int (*residual)(Mat,Vec,Vec,Vec),Mat mat)
87: {
88: MG *mg = (MG*)pc->data;
91: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
93: mg[l]->residual = residual;
94: mg[l]->A = mat;
95: return(0);
96: }
100: /*@
101: MGSetInterpolate - Sets the function to be used to calculate the
102: interpolation on the lth level.
104: Collective on PC and Mat
106: Input Parameters:
107: + pc - the multigrid context
108: . mat - the interpolation operator
109: - l - the level (0 is coarsest) to supply
111: Level: advanced
113: Notes:
114: Usually this is the same matrix used also to set the restriction
115: for the same level.
117: One can pass in the interpolation matrix or its transpose; PETSc figures
118: out from the matrix size which one it is.
120: .keywords: multigrid, set, interpolate, level
122: .seealso: MGSetRestriction()
123: @*/
124: int MGSetInterpolate(PC pc,int l,Mat mat)
125: {
126: MG *mg = (MG*)pc->data;
129: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
130: mg[l]->interpolate = mat;
131: return(0);
132: }
136: /*@
137: MGSetRestriction - Sets the function to be used to restrict vector
138: from level l to l-1.
140: Collective on PC and Mat
142: Input Parameters:
143: + pc - the multigrid context
144: . mat - the restriction matrix
145: - l - the level (0 is coarsest) to supply
147: Level: advanced
149: Notes:
150: Usually this is the same matrix used also to set the interpolation
151: for the same level.
153: One can pass in the interpolation matrix or its transpose; PETSc figures
154: out from the matrix size which one it is.
156: .keywords: MG, set, multigrid, restriction, level
158: .seealso: MGSetInterpolate()
159: @*/
160: int MGSetRestriction(PC pc,int l,Mat mat)
161: {
162: MG *mg = (MG*)pc->data;
165: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
166: mg[l]->restrct = mat;
167: return(0);
168: }
172: /*@C
173: MGGetSmoother - Gets the SLES context to be used as smoother for
174: both pre- and post-smoothing. Call both MGGetSmootherUp() and
175: MGGetSmootherDown() to use different functions for pre- and
176: post-smoothing.
178: Not Collective, SLES returned is parallel if PC is
180: Input Parameters:
181: + pc - the multigrid context
182: - l - the level (0 is coarsest) to supply
184: Ouput Parameters:
185: . sles - the smoother
187: Level: advanced
189: .keywords: MG, get, multigrid, level, smoother, pre-smoother, post-smoother
191: .seealso: MGGetSmootherUp(), MGGetSmootherDown()
192: @*/
193: int MGGetSmoother(PC pc,int l,SLES *sles)
194: {
195: MG *mg = (MG*)pc->data;
198: *sles = mg[l]->smoothd;
199: return(0);
200: }
204: /*@C
205: MGGetSmootherUp - Gets the SLES context to be used as smoother after
206: coarse grid correction (post-smoother).
208: Not Collective, SLES returned is parallel if PC is
210: Input Parameters:
211: + pc - the multigrid context
212: - l - the level (0 is coarsest) to supply
214: Ouput Parameters:
215: . sles - the smoother
217: Level: advanced
219: .keywords: MG, multigrid, get, smoother, up, post-smoother, level
221: .seealso: MGGetSmootherUp(), MGGetSmootherDown()
222: @*/
223: int MGGetSmootherUp(PC pc,int l,SLES *sles)
224: {
225: MG *mg = (MG*)pc->data;
226: int ierr;
227: char *prefix;
228: KSP ksp;
229: MPI_Comm comm;
232: /*
233: This is called only if user wants a different pre-smoother from post.
234: Thus we check if a different one has already been allocated,
235: if not we allocate it.
236: */
237: PCGetOptionsPrefix(pc,&prefix);
239: if (mg[l]->smoothu == mg[l]->smoothd) {
240: PetscObjectGetComm((PetscObject)mg[l]->smoothd,&comm);
241: SLESCreate(comm,&mg[l]->smoothu);
242: SLESGetKSP(mg[l]->smoothd,&ksp);
243: KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);
244: SLESSetOptionsPrefix(mg[l]->smoothu,prefix);
245: SLESAppendOptionsPrefix(mg[l]->smoothd,"mg_levels_");
246: PetscLogObjectParent(pc,mg[l]->smoothu);
247: }
248: if (sles) *sles = mg[l]->smoothu;
249: return(0);
250: }
254: /*@C
255: MGGetSmootherDown - Gets the SLES context to be used as smoother before
256: coarse grid correction (pre-smoother).
258: Not Collective, SLES returned is parallel if PC is
260: Input Parameters:
261: + pc - the multigrid context
262: - l - the level (0 is coarsest) to supply
264: Ouput Parameters:
265: . sles - the smoother
267: Level: advanced
269: .keywords: MG, multigrid, get, smoother, down, pre-smoother, level
271: .seealso: MGGetSmootherUp(), MGGetSmoother()
272: @*/
273: int MGGetSmootherDown(PC pc,int l,SLES *sles)
274: {
276: MG *mg = (MG*)pc->data;
279: /* make sure smoother up and down are different */
280: MGGetSmootherUp(pc,l,PETSC_NULL);
281: *sles = mg[l]->smoothd;
282: return(0);
283: }
287: /*@
288: MGSetCyclesOnLevel - Sets the number of cycles to run on this level.
290: Collective on PC
292: Input Parameters:
293: + pc - the multigrid context
294: . l - the level (0 is coarsest) this is to be used for
295: - n - the number of cycles
297: Level: advanced
299: .keywords: MG, multigrid, set, cycles, V-cycle, W-cycle, level
301: .seealso: MGSetCycles()
302: @*/
303: int MGSetCyclesOnLevel(PC pc,int l,int c)
304: {
305: MG *mg = (MG*)pc->data;
308: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
309: mg[l]->cycles = c;
310: return(0);
311: }
315: /*@
316: MGSetRhs - Sets the vector space to be used to store the right-hand side
317: on a particular level. The user should free this space at the conclusion
318: of multigrid use.
320: Collective on PC and Vec
322: Input Parameters:
323: + pc - the multigrid context
324: . l - the level (0 is coarsest) this is to be used for
325: - c - the space
327: Level: advanced
329: .keywords: MG, multigrid, set, right-hand-side, rhs, level
331: .seealso: MGSetX(), MGSetR()
332: @*/
333: int MGSetRhs(PC pc,int l,Vec c)
334: {
335: MG *mg = (MG*)pc->data;
338: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
339: mg[l]->b = c;
340: return(0);
341: }
345: /*@
346: MGSetX - Sets the vector space to be used to store the solution on a
347: particular level. The user should free this space at the conclusion
348: of multigrid use.
350: Collective on PC and Vec
352: Input Parameters:
353: + pc - the multigrid context
354: . l - the level (0 is coarsest) this is to be used for
355: - c - the space
357: Level: advanced
359: .keywords: MG, multigrid, set, solution, level
361: .seealso: MGSetRhs(), MGSetR()
362: @*/
363: int MGSetX(PC pc,int l,Vec c)
364: {
365: MG *mg = (MG*)pc->data;
368: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
369: mg[l]->x = c;
370: return(0);
371: }
375: /*@
376: MGSetR - Sets the vector space to be used to store the residual on a
377: particular level. The user should free this space at the conclusion of
378: multigrid use.
380: Collective on PC and Vec
382: Input Parameters:
383: + pc - the multigrid context
384: . l - the level (0 is coarsest) this is to be used for
385: - c - the space
387: Level: advanced
389: .keywords: MG, multigrid, set, residual, level
390: @*/
391: int MGSetR(PC pc,int l,Vec c)
392: {
393: MG *mg = (MG*)pc->data;
396: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
397: mg[l]->r = c;
398: return(0);
399: }