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