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 PETSCKSP_DLLEXPORT PCMGDefaultResidual(Mat mat,Vec b,Vec x,Vec r)
28: {
30: PetscScalar mone = -1.0;
33: MatMult(mat,x,r);
34: VecAYPX(r,mone,b);
35: return(0);
36: }
38: /* ---------------------------------------------------------------------------*/
42: /*@C
43: PCMGGetCoarseSolve - 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: . ksp - the coarse grid solver context
53: Level: advanced
55: .keywords: MG, multigrid, get, coarse grid
56: @*/
57: PetscErrorCode PETSCKSP_DLLEXPORT PCMGGetCoarseSolve(PC pc,KSP *ksp)
58: {
59: PC_MG **mg = (PC_MG**)pc->data;
62: *ksp = mg[0]->smoothd;
63: return(0);
64: }
68: /*@C
69: PCMGSetResidual - 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 PCMGDefaultResidual)
78: - mat - matrix associated with residual
80: Level: advanced
82: .keywords: MG, set, multigrid, residual, level
84: .seealso: PCMGDefaultResidual()
85: @*/
86: PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetResidual(PC pc,PetscInt l,PetscErrorCode (*residual)(Mat,Vec,Vec,Vec),Mat mat)
87: {
88: PC_MG **mg = (PC_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: PCMGSetInterpolate - 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: If you do not set this, the transpose of the Mat set with PCMGSetRestriction()
121: is used.
123: .keywords: multigrid, set, interpolate, level
125: .seealso: PCMGSetRestriction()
126: @*/
127: PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetInterpolate(PC pc,PetscInt l,Mat mat)
128: {
129: PC_MG **mg = (PC_MG**)pc->data;
133: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
134: if (!l) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Do not set interpolation routine for coarsest level");
135: if (mg[l]->interpolate) {MatDestroy(mg[l]->interpolate);}
136: mg[l]->interpolate = mat;
137: PetscObjectReference((PetscObject)mat);
138: return(0);
139: }
143: /*@
144: PCMGSetRestriction - Sets the function to be used to restrict vector
145: from level l to l-1.
147: Collective on PC and Mat
149: Input Parameters:
150: + pc - the multigrid context
151: . mat - the restriction matrix
152: - l - the level (0 is coarsest) to supply
154: Level: advanced
156: Notes:
157: Usually this is the same matrix used also to set the interpolation
158: for the same level.
160: One can pass in the interpolation matrix or its transpose; PETSc figures
161: out from the matrix size which one it is.
163: If you do not set this, the transpose of the Mat set with PCMGSetInterpolate()
164: is used.
166: .keywords: MG, set, multigrid, restriction, level
168: .seealso: PCMGSetInterpolate()
169: @*/
170: PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetRestriction(PC pc,PetscInt l,Mat mat)
171: {
173: PC_MG **mg = (PC_MG**)pc->data;
176: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
177: if (!l) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Do not set restriction routine for coarsest level");
178: if (mg[l]->restrct) {MatDestroy(mg[l]->restrct);}
179: mg[l]->restrct = mat;
180: PetscObjectReference((PetscObject)mat);
181: return(0);
182: }
186: /*@C
187: PCMGGetSmoother - Gets the KSP context to be used as smoother for
188: both pre- and post-smoothing. Call both PCMGGetSmootherUp() and
189: PCMGGetSmootherDown() to use different functions for pre- and
190: post-smoothing.
192: Not Collective, KSP returned is parallel if PC is
194: Input Parameters:
195: + pc - the multigrid context
196: - l - the level (0 is coarsest) to supply
198: Ouput Parameters:
199: . ksp - the smoother
201: Level: advanced
203: .keywords: MG, get, multigrid, level, smoother, pre-smoother, post-smoother
205: .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown()
206: @*/
207: PetscErrorCode PETSCKSP_DLLEXPORT PCMGGetSmoother(PC pc,PetscInt l,KSP *ksp)
208: {
209: PC_MG **mg = (PC_MG**)pc->data;
212: *ksp = mg[l]->smoothd;
213: return(0);
214: }
218: /*@C
219: PCMGGetSmootherUp - Gets the KSP context to be used as smoother after
220: coarse grid correction (post-smoother).
222: Not Collective, KSP returned is parallel if PC is
224: Input Parameters:
225: + pc - the multigrid context
226: - l - the level (0 is coarsest) to supply
228: Ouput Parameters:
229: . ksp - the smoother
231: Level: advanced
233: .keywords: MG, multigrid, get, smoother, up, post-smoother, level
235: .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown()
236: @*/
237: PetscErrorCode PETSCKSP_DLLEXPORT PCMGGetSmootherUp(PC pc,PetscInt l,KSP *ksp)
238: {
239: PC_MG **mg = (PC_MG**)pc->data;
241: const char *prefix;
242: MPI_Comm comm;
245: /*
246: This is called only if user wants a different pre-smoother from post.
247: Thus we check if a different one has already been allocated,
248: if not we allocate it.
249: */
250: if (!l) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"There is no such thing as a up smoother on the coarse grid");
251: if (mg[l]->smoothu == mg[l]->smoothd) {
252: PetscObjectGetComm((PetscObject)mg[l]->smoothd,&comm);
253: KSPGetOptionsPrefix(mg[l]->smoothd,&prefix);
254: KSPCreate(comm,&mg[l]->smoothu);
255: KSPSetTolerances(mg[l]->smoothu,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);
256: KSPSetOptionsPrefix(mg[l]->smoothu,prefix);
257: PetscLogObjectParent(pc,mg[l]->smoothu);
258: }
259: if (ksp) *ksp = mg[l]->smoothu;
260: return(0);
261: }
265: /*@C
266: PCMGGetSmootherDown - Gets the KSP context to be used as smoother before
267: coarse grid correction (pre-smoother).
269: Not Collective, KSP returned is parallel if PC is
271: Input Parameters:
272: + pc - the multigrid context
273: - l - the level (0 is coarsest) to supply
275: Ouput Parameters:
276: . ksp - the smoother
278: Level: advanced
280: .keywords: MG, multigrid, get, smoother, down, pre-smoother, level
282: .seealso: PCMGGetSmootherUp(), PCMGGetSmoother()
283: @*/
284: PetscErrorCode PETSCKSP_DLLEXPORT PCMGGetSmootherDown(PC pc,PetscInt l,KSP *ksp)
285: {
287: PC_MG **mg = (PC_MG**)pc->data;
290: /* make sure smoother up and down are different */
291: PCMGGetSmootherUp(pc,l,PETSC_NULL);
292: *ksp = mg[l]->smoothd;
293: return(0);
294: }
298: /*@
299: PCMGSetCyclesOnLevel - Sets the number of cycles to run on this level.
301: Collective on PC
303: Input Parameters:
304: + pc - the multigrid context
305: . l - the level (0 is coarsest) this is to be used for
306: - n - the number of cycles
308: Level: advanced
310: .keywords: MG, multigrid, set, cycles, V-cycle, W-cycle, level
312: .seealso: PCMGSetCycles()
313: @*/
314: PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetCyclesOnLevel(PC pc,PetscInt l,PetscInt c)
315: {
316: PC_MG **mg = (PC_MG**)pc->data;
319: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
320: mg[l]->cycles = c;
321: return(0);
322: }
326: /*@
327: PCMGSetRhs - Sets the vector space to be used to store the right-hand side
328: on a particular level.
330: Collective on PC and Vec
332: Input Parameters:
333: + pc - the multigrid context
334: . l - the level (0 is coarsest) this is to be used for
335: - c - the space
337: Level: advanced
339: Notes: If this is not provided PETSc will automatically generate one.
341: You do not need to keep a reference to this vector if you do
342: not need it PCDestroy() will properly free it.
344: .keywords: MG, multigrid, set, right-hand-side, rhs, level
346: .seealso: PCMGSetX(), PCMGSetR()
347: @*/
348: PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetRhs(PC pc,PetscInt l,Vec c)
349: {
351: PC_MG **mg = (PC_MG**)pc->data;
354: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
355: if (l == mg[0]->levels-1) SETERRQ(PETSC_ERR_ARG_INCOMP,"Do not set rhs for finest level");
356: if (mg[l]->b) {VecDestroy(mg[l]->b);}
357: mg[l]->b = c;
358: PetscObjectReference((PetscObject)c);
359: return(0);
360: }
364: /*@
365: PCMGSetX - Sets the vector space to be used to store the solution on a
366: particular level.
368: Collective on PC and Vec
370: Input Parameters:
371: + pc - the multigrid context
372: . l - the level (0 is coarsest) this is to be used for
373: - c - the space
375: Level: advanced
377: Notes: If this is not provided PETSc will automatically generate one.
379: You do not need to keep a reference to this vector if you do
380: not need it PCDestroy() will properly free it.
382: .keywords: MG, multigrid, set, solution, level
384: .seealso: PCMGSetRhs(), PCMGSetR()
385: @*/
386: PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetX(PC pc,PetscInt l,Vec c)
387: {
389: PC_MG **mg = (PC_MG**)pc->data;
392: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
393: if (l == mg[0]->levels-1) SETERRQ(PETSC_ERR_ARG_INCOMP,"Do not set rhs for finest level");
394: if (mg[l]->x) {VecDestroy(mg[l]->x);}
395: mg[l]->x = c;
396: PetscObjectReference((PetscObject)c);
397: return(0);
398: }
402: /*@
403: PCMGSetR - Sets the vector space to be used to store the residual on a
404: particular level.
406: Collective on PC and Vec
408: Input Parameters:
409: + pc - the multigrid context
410: . l - the level (0 is coarsest) this is to be used for
411: - c - the space
413: Level: advanced
415: Notes: If this is not provided PETSc will automatically generate one.
417: You do not need to keep a reference to this vector if you do
418: not need it PCDestroy() will properly free it.
420: .keywords: MG, multigrid, set, residual, level
421: @*/
422: PetscErrorCode PETSCKSP_DLLEXPORT PCMGSetR(PC pc,PetscInt l,Vec c)
423: {
425: PC_MG **mg = (PC_MG**)pc->data;
428: if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
429: if (!l) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Need not set residual vector for coarse grid");
430: if (mg[l]->r) {VecDestroy(mg[l]->r);}
431: mg[l]->r = c;
432: PetscObjectReference((PetscObject)c);
433: return(0);
434: }