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*/
6: /*@C
7: MGDefaultResidual - Default routine to calculate the residual.
9: Collective on Mat and Vec
11: Input Parameters:
12: + mat - the matrix
13: . b - the right-hand-side
14: - x - the approximate solution
15:
16: Output Parameter:
17: . r - location to store the residual
19: Level: advanced
21: .keywords: MG, default, multigrid, residual
23: .seealso: MGSetResidual()
24: @*/
25: int MGDefaultResidual(Mat mat,Vec b,Vec x,Vec r)
26: {
27: int ierr;
28: PetscScalar mone = -1.0;
31: MatMult(mat,x,r);
32: VecAYPX(&mone,b,r);
33: return(0);
34: }
36: /* ---------------------------------------------------------------------------*/
38: /*@C
39: MGGetCoarseSolve - Gets the solver context to be used on the coarse grid.
41: Not Collective
43: Input Parameter:
44: . pc - the multigrid context
46: Output Parameter:
47: . sles - the coarse grid solver context
49: Level: advanced
51: .keywords: MG, multigrid, get, coarse grid
52: @*/
53: int MGGetCoarseSolve(PC pc,SLES *sles)
54: {
55: MG *mg = (MG*)pc->data;
58: *sles = mg[0]->smoothd;
59: return(0);
60: }
62: /*@C
63: MGSetResidual - Sets the function to be used to calculate the residual
64: on the lth level.
66: Collective on PC and Mat
68: Input Parameters:
69: + pc - the multigrid context
70: . l - the level to supply
71: . residual - function used to form residual (usually MGDefaultResidual)
72: - mat - matrix associated with residual
74: Level: advanced
76: .keywords: MG, set, multigrid, residual, level
78: .seealso: MGDefaultResidual()
79: @*/
80: int MGSetResidual(PC pc,int l,int (*residual)(Mat,Vec,Vec,Vec),Mat mat)
81: {
82: MG *mg = (MG*)pc->data;
85: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
87: mg[l]->residual = residual;
88: mg[l]->A = mat;
89: return(0);
90: }
92: /*@
93: MGSetInterpolate - Sets the function to be used to calculate the
94: interpolation on the lth level.
96: Collective on PC and Mat
98: Input Parameters:
99: + pc - the multigrid context
100: . mat - the interpolation operator
101: - l - the level to supply
103: Level: advanced
105: Notes:
106: Usually this is the same matrix used also to set the restriction
107: for the same level.
109: One can pass in the interpolation matrix or its transpose; PETSc figures
110: out from the matrix size which one it is.
112: .keywords: multigrid, set, interpolate, level
114: .seealso: MGSetRestriction()
115: @*/
116: int MGSetInterpolate(PC pc,int l,Mat mat)
117: {
118: MG *mg = (MG*)pc->data;
121: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
122: mg[l]->interpolate = mat;
123: return(0);
124: }
126: /*@
127: MGSetRestriction - Sets the function to be used to restrict vector
128: from level l to l-1.
130: Collective on PC and Mat
132: Input Parameters:
133: + pc - the multigrid context
134: . mat - the restriction matrix
135: - l - the level to supply
137: Level: advanced
139: Notes:
140: Usually this is the same matrix used also to set the interpolation
141: for the same level.
143: One can pass in the interpolation matrix or its transpose; PETSc figures
144: out from the matrix size which one it is.
146: .keywords: MG, set, multigrid, restriction, level
148: .seealso: MGSetInterpolate()
149: @*/
150: int MGSetRestriction(PC pc,int l,Mat mat)
151: {
152: MG *mg = (MG*)pc->data;
155: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
156: mg[l]->restrct = mat;
157: return(0);
158: }
160: /*@C
161: MGGetSmoother - Gets the SLES context to be used as smoother for
162: both pre- and post-smoothing. Call both MGGetSmootherUp() and
163: MGGetSmootherDown() to use different functions for pre- and
164: post-smoothing.
166: Not Collective, SLES returned is parallel if PC is
168: Input Parameters:
169: + pc - the multigrid context
170: - l - the level to supply
172: Ouput Parameters:
173: . sles - the smoother
175: Level: advanced
177: .keywords: MG, get, multigrid, level, smoother, pre-smoother, post-smoother
179: .seealso: MGGetSmootherUp(), MGGetSmootherDown()
180: @*/
181: int MGGetSmoother(PC pc,int l,SLES *sles)
182: {
183: MG *mg = (MG*)pc->data;
186: *sles = mg[l]->smoothd;
187: return(0);
188: }
190: /*@C
191: MGGetSmootherUp - Gets the SLES context to be used as smoother after
192: coarse grid correction (post-smoother).
194: Not Collective, SLES returned is parallel if PC is
196: Input Parameters:
197: + pc - the multigrid context
198: - l - the level to supply
200: Ouput Parameters:
201: . sles - the smoother
203: Level: advanced
205: .keywords: MG, multigrid, get, smoother, up, post-smoother, level
207: .seealso: MGGetSmootherUp(), MGGetSmootherDown()
208: @*/
209: int MGGetSmootherUp(PC pc,int l,SLES *sles)
210: {
211: MG *mg = (MG*)pc->data;
212: int ierr;
213: char *prefix;
214: KSP ksp;
215: MPI_Comm comm;
218: /*
219: This is called only if user wants a different pre-smoother from post.
220: Thus we check if a different one has already been allocated,
221: if not we allocate it.
222: */
223: PCGetOptionsPrefix(pc,&prefix);
225: if (mg[l]->smoothu == mg[l]->smoothd) {
226: PetscObjectGetComm((PetscObject)mg[l]->smoothd,&comm);
227: SLESCreate(comm,&mg[l]->smoothu);
228: SLESGetKSP(mg[l]->smoothd,&ksp);
229: KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);
230: SLESSetOptionsPrefix(mg[l]->smoothu,prefix);
231: SLESAppendOptionsPrefix(mg[l]->smoothd,"mg_levels_");
232: PetscLogObjectParent(pc,mg[l]->smoothu);
233: }
234: *sles = mg[l]->smoothu;
235: return(0);
236: }
238: /*@C
239: MGGetSmootherDown - Gets the SLES context to be used as smoother before
240: coarse grid correction (pre-smoother).
242: Not Collective, SLES returned is parallel if PC is
244: Input Parameters:
245: + pc - the multigrid context
246: - l - the level to supply
248: Ouput Parameters:
249: . sles - the smoother
251: Level: advanced
253: .keywords: MG, multigrid, get, smoother, down, pre-smoother, level
255: .seealso: MGGetSmootherUp(), MGGetSmoother()
256: @*/
257: int MGGetSmootherDown(PC pc,int l,SLES *sles)
258: {
259: MG *mg = (MG*)pc->data;
262: *sles = mg[l]->smoothd;
263: return(0);
264: }
266: /*@
267: MGSetCyclesOnLevel - Sets the number of cycles to run on this level.
269: Collective on PC
271: Input Parameters:
272: + pc - the multigrid context
273: . l - the level this is to be used for
274: - n - the number of cycles
276: Level: advanced
278: .keywords: MG, multigrid, set, cycles, V-cycle, W-cycle, level
280: .seealso: MGSetCycles()
281: @*/
282: int MGSetCyclesOnLevel(PC pc,int l,int c)
283: {
284: MG *mg = (MG*)pc->data;
287: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
288: mg[l]->cycles = c;
289: return(0);
290: }
292: /*@
293: MGSetRhs - Sets the vector space to be used to store the right-hand side
294: on a particular level. The user should free this space at the conclusion
295: of multigrid use.
297: Collective on PC and Vec
299: Input Parameters:
300: + pc - the multigrid context
301: . l - the level this is to be used for
302: - c - the space
304: Level: advanced
306: .keywords: MG, multigrid, set, right-hand-side, rhs, level
308: .seealso: MGSetX(), MGSetR()
309: @*/
310: int MGSetRhs(PC pc,int l,Vec c)
311: {
312: MG *mg = (MG*)pc->data;
315: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
316: mg[l]->b = c;
317: return(0);
318: }
320: /*@
321: MGSetX - Sets the vector space to be used to store the solution on a
322: particular level. The user should free this space at the conclusion
323: of multigrid use.
325: Collective on PC and Vec
327: Input Parameters:
328: + pc - the multigrid context
329: . l - the level this is to be used for
330: - c - the space
332: Level: advanced
334: .keywords: MG, multigrid, set, solution, level
336: .seealso: MGSetRhs(), MGSetR()
337: @*/
338: int MGSetX(PC pc,int l,Vec c)
339: {
340: MG *mg = (MG*)pc->data;
343: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
344: mg[l]->x = c;
345: return(0);
346: }
348: /*@
349: MGSetR - Sets the vector space to be used to store the residual on a
350: particular level. The user should free this space at the conclusion of
351: multigrid use.
353: Collective on PC and Vec
355: Input Parameters:
356: + pc - the multigrid context
357: . l - the level this is to be used for
358: - c - the space
360: Level: advanced
362: .keywords: MG, multigrid, set, residual, level
363: @*/
364: int MGSetR(PC pc,int l,Vec c)
365: {
366: MG *mg = (MG*)pc->data;
369: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
370: mg[l]->r = c;
371: return(0);
372: }