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: }