Actual source code: mgfunc.c
1: #define PETSCKSP_DLL
3: #include src/ksp/pc/impls/mg/mgimpl.h
4: /*I "petscmg.h" I*/
8: /*@C
9: PCMGDefaultResidual - 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: PCMGSetResidual()
26: @*/
27: PetscErrorCode PCMGDefaultResidual(Mat mat,Vec b,Vec x,Vec r)
28: {
32: MatMult(mat,x,r);
33: VecAYPX(r,-1.0,b);
34: return(0);
35: }
37: /* ---------------------------------------------------------------------------*/
41: /*@
42: PCMGGetCoarseSolve - Gets the solver context to be used on the coarse grid.
44: Not Collective
46: Input Parameter:
47: . pc - the multigrid context
49: Output Parameter:
50: . ksp - the coarse grid solver context
52: Level: advanced
54: .keywords: MG, multigrid, get, coarse grid
55: @*/
56: PetscErrorCode PCMGGetCoarseSolve(PC pc,KSP *ksp)
57: {
58: PC_MG **mg = (PC_MG**)pc->data;
61: *ksp = mg[0]->smoothd;
62: return(0);
63: }
67: /*@C
68: PCMGSetResidual - Sets the function to be used to calculate the residual
69: on the lth level.
71: Collective on PC and Mat
73: Input Parameters:
74: + pc - the multigrid context
75: . l - the level (0 is coarsest) to supply
76: . residual - function used to form residual (usually PCMGDefaultResidual)
77: - mat - matrix associated with residual
79: Level: advanced
81: .keywords: MG, set, multigrid, residual, level
83: .seealso: PCMGDefaultResidual()
84: @*/
85: PetscErrorCode PCMGSetResidual(PC pc,PetscInt l,PetscErrorCode (*residual)(Mat,Vec,Vec,Vec),Mat mat)
86: {
87: PC_MG **mg = (PC_MG**)pc->data;
90: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
92: mg[l]->residual = residual;
93: mg[l]->A = mat;
94: return(0);
95: }
99: /*@
100: PCMGSetInterpolate - Sets the function to be used to calculate the
101: interpolation on the lth level.
103: Collective on PC and Mat
105: Input Parameters:
106: + pc - the multigrid context
107: . mat - the interpolation operator
108: - l - the level (0 is coarsest) to supply
110: Level: advanced
112: Notes:
113: Usually this is the same matrix used also to set the restriction
114: for the same level.
116: One can pass in the interpolation matrix or its transpose; PETSc figures
117: out from the matrix size which one it is.
119: If you do not set this, the transpose of the Mat set with PCMGSetRestriction()
120: is used.
122: .keywords: multigrid, set, interpolate, level
124: .seealso: PCMGSetRestriction()
125: @*/
126: PetscErrorCode PCMGSetInterpolate(PC pc,PetscInt l,Mat mat)
127: {
128: PC_MG **mg = (PC_MG**)pc->data;
132: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
133: if (!l) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Do not set interpolation routine for coarsest level");
134: if (mg[l]->interpolate) {MatDestroy(mg[l]->interpolate);}
135: mg[l]->interpolate = mat;
136: PetscObjectReference((PetscObject)mat);
137: return(0);
138: }
142: /*@
143: PCMGSetRestriction - Sets the function to be used to restrict vector
144: from level l to l-1.
146: Collective on PC and Mat
148: Input Parameters:
149: + pc - the multigrid context
150: . mat - the restriction matrix
151: - l - the level (0 is coarsest) to supply
153: Level: advanced
155: Notes:
156: Usually this is the same matrix used also to set the interpolation
157: for the same level.
159: One can pass in the interpolation matrix or its transpose; PETSc figures
160: out from the matrix size which one it is.
162: If you do not set this, the transpose of the Mat set with PCMGSetInterpolate()
163: is used.
165: .keywords: MG, set, multigrid, restriction, level
167: .seealso: PCMGSetInterpolate()
168: @*/
169: PetscErrorCode PCMGSetRestriction(PC pc,PetscInt l,Mat mat)
170: {
172: PC_MG **mg = (PC_MG**)pc->data;
175: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
176: if (!l) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Do not set restriction routine for coarsest level");
177: if (mg[l]->restrct) {MatDestroy(mg[l]->restrct);}
178: mg[l]->restrct = mat;
179: PetscObjectReference((PetscObject)mat);
180: return(0);
181: }
185: /*@
186: PCMGGetSmoother - Gets the KSP context to be used as smoother for
187: both pre- and post-smoothing. Call both PCMGGetSmootherUp() and
188: PCMGGetSmootherDown() to use different functions for pre- and
189: post-smoothing.
191: Not Collective, KSP returned is parallel if PC is
193: Input Parameters:
194: + pc - the multigrid context
195: - l - the level (0 is coarsest) to supply
197: Ouput Parameters:
198: . ksp - the smoother
200: Level: advanced
202: .keywords: MG, get, multigrid, level, smoother, pre-smoother, post-smoother
204: .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown()
205: @*/
206: PetscErrorCode PCMGGetSmoother(PC pc,PetscInt l,KSP *ksp)
207: {
208: PC_MG **mg = (PC_MG**)pc->data;
211: *ksp = mg[l]->smoothd;
212: return(0);
213: }
217: /*@
218: PCMGGetSmootherUp - Gets the KSP context to be used as smoother after
219: coarse grid correction (post-smoother).
221: Not Collective, KSP returned is parallel if PC is
223: Input Parameters:
224: + pc - the multigrid context
225: - l - the level (0 is coarsest) to supply
227: Ouput Parameters:
228: . ksp - the smoother
230: Level: advanced
232: .keywords: MG, multigrid, get, smoother, up, post-smoother, level
234: .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown()
235: @*/
236: PetscErrorCode PCMGGetSmootherUp(PC pc,PetscInt l,KSP *ksp)
237: {
238: PC_MG **mg = (PC_MG**)pc->data;
240: const char *prefix;
241: MPI_Comm comm;
244: /*
245: This is called only if user wants a different pre-smoother from post.
246: Thus we check if a different one has already been allocated,
247: if not we allocate it.
248: */
249: if (!l) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"There is no such thing as a up smoother on the coarse grid");
250: if (mg[l]->smoothu == mg[l]->smoothd) {
251: PetscObjectGetComm((PetscObject)mg[l]->smoothd,&comm);
252: KSPGetOptionsPrefix(mg[l]->smoothd,&prefix);
253: KSPCreate(comm,&mg[l]->smoothu);
254: KSPSetTolerances(mg[l]->smoothu,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);
255: KSPSetOptionsPrefix(mg[l]->smoothu,prefix);
256: PetscLogObjectParent(pc,mg[l]->smoothu);
257: }
258: if (ksp) *ksp = mg[l]->smoothu;
259: return(0);
260: }
264: /*@
265: PCMGGetSmootherDown - Gets the KSP context to be used as smoother before
266: coarse grid correction (pre-smoother).
268: Not Collective, KSP returned is parallel if PC is
270: Input Parameters:
271: + pc - the multigrid context
272: - l - the level (0 is coarsest) to supply
274: Ouput Parameters:
275: . ksp - the smoother
277: Level: advanced
279: .keywords: MG, multigrid, get, smoother, down, pre-smoother, level
281: .seealso: PCMGGetSmootherUp(), PCMGGetSmoother()
282: @*/
283: PetscErrorCode PCMGGetSmootherDown(PC pc,PetscInt l,KSP *ksp)
284: {
286: PC_MG **mg = (PC_MG**)pc->data;
289: /* make sure smoother up and down are different */
290: if (l != 0) {
291: PCMGGetSmootherUp(pc,l,PETSC_NULL);
292: }
293: *ksp = mg[l]->smoothd;
294: return(0);
295: }
299: /*@
300: PCMGSetCyclesOnLevel - Sets the number of cycles to run on this level.
302: Collective on PC
304: Input Parameters:
305: + pc - the multigrid context
306: . l - the level (0 is coarsest) this is to be used for
307: - n - the number of cycles
309: Level: advanced
311: .keywords: MG, multigrid, set, cycles, V-cycle, W-cycle, level
313: .seealso: PCMGSetCycles()
314: @*/
315: PetscErrorCode PCMGSetCyclesOnLevel(PC pc,PetscInt l,PetscInt c)
316: {
317: PC_MG **mg = (PC_MG**)pc->data;
320: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
321: mg[l]->cycles = c;
322: return(0);
323: }
327: /*@
328: PCMGSetRhs - Sets the vector space to be used to store the right-hand side
329: on a particular level.
331: Collective on PC and Vec
333: Input Parameters:
334: + pc - the multigrid context
335: . l - the level (0 is coarsest) this is to be used for
336: - c - the space
338: Level: advanced
340: Notes: If this is not provided PETSc will automatically generate one.
342: You do not need to keep a reference to this vector if you do
343: not need it PCDestroy() will properly free it.
345: .keywords: MG, multigrid, set, right-hand-side, rhs, level
347: .seealso: PCMGSetX(), PCMGSetR()
348: @*/
349: PetscErrorCode PCMGSetRhs(PC pc,PetscInt l,Vec c)
350: {
352: PC_MG **mg = (PC_MG**)pc->data;
355: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
356: if (l == mg[0]->levels-1) SETERRQ(PETSC_ERR_ARG_INCOMP,"Do not set rhs for finest level");
357: if (mg[l]->b) {VecDestroy(mg[l]->b);}
358: mg[l]->b = c;
359: PetscObjectReference((PetscObject)c);
360: return(0);
361: }
365: /*@
366: PCMGSetX - Sets the vector space to be used to store the solution on a
367: particular level.
369: Collective on PC and Vec
371: Input Parameters:
372: + pc - the multigrid context
373: . l - the level (0 is coarsest) this is to be used for
374: - c - the space
376: Level: advanced
378: Notes: If this is not provided PETSc will automatically generate one.
380: You do not need to keep a reference to this vector if you do
381: not need it PCDestroy() will properly free it.
383: .keywords: MG, multigrid, set, solution, level
385: .seealso: PCMGSetRhs(), PCMGSetR()
386: @*/
387: PetscErrorCode PCMGSetX(PC pc,PetscInt l,Vec c)
388: {
390: PC_MG **mg = (PC_MG**)pc->data;
393: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
394: if (l == mg[0]->levels-1) SETERRQ(PETSC_ERR_ARG_INCOMP,"Do not set rhs for finest level");
395: if (mg[l]->x) {VecDestroy(mg[l]->x);}
396: mg[l]->x = c;
397: PetscObjectReference((PetscObject)c);
398: return(0);
399: }
403: /*@
404: PCMGSetR - Sets the vector space to be used to store the residual on a
405: particular level.
407: Collective on PC and Vec
409: Input Parameters:
410: + pc - the multigrid context
411: . l - the level (0 is coarsest) this is to be used for
412: - c - the space
414: Level: advanced
416: Notes: If this is not provided PETSc will automatically generate one.
418: You do not need to keep a reference to this vector if you do
419: not need it PCDestroy() will properly free it.
421: .keywords: MG, multigrid, set, residual, level
422: @*/
423: PetscErrorCode PCMGSetR(PC pc,PetscInt l,Vec c)
424: {
426: PC_MG **mg = (PC_MG**)pc->data;
429: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
430: if (!l) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Need not set residual vector for coarse grid");
431: if (mg[l]->r) {VecDestroy(mg[l]->r);}
432: mg[l]->r = c;
433: PetscObjectReference((PetscObject)c);
434: return(0);
435: }