Actual source code: mgfunc.c

  1: /*$Id: mgfunc.c,v 1.41 2001/08/07 03:03:36 balay Exp $*/

 3:  #include src/ksp/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: .  ksp - the coarse grid solver context 

 53:    Level: advanced

 55: .keywords: MG, multigrid, get, coarse grid
 56: @*/
 57: int MGGetCoarseSolve(PC pc,KSP *ksp)
 58: {
 59:   MG *mg = (MG*)pc->data;

 62:   *ksp =  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 KSP 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, KSP 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: .  ksp - 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,KSP *ksp)
194: {
195:   MG *mg = (MG*)pc->data;

198:   *ksp = mg[l]->smoothd;
199:   return(0);
200: }

204: /*@C
205:    MGGetSmootherUp - Gets the KSP context to be used as smoother after 
206:    coarse grid correction (post-smoother). 

208:    Not Collective, KSP 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: .  ksp - 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,KSP *ksp)
224: {
225:   MG       *mg = (MG*)pc->data;
226:   int      ierr;
227:   char     *prefix;
228:   MPI_Comm comm;

231:   /*
232:      This is called only if user wants a different pre-smoother from post.
233:      Thus we check if a different one has already been allocated, 
234:      if not we allocate it.
235:   */
236:   PCGetOptionsPrefix(pc,&prefix);

238:   if (mg[l]->smoothu == mg[l]->smoothd) {
239:     PetscObjectGetComm((PetscObject)mg[l]->smoothd,&comm);
240:     KSPCreate(comm,&mg[l]->smoothu);
241:     KSPSetTolerances(mg[l]->smoothd,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);
242:     KSPSetOptionsPrefix(mg[l]->smoothu,prefix);
243:     KSPAppendOptionsPrefix(mg[l]->smoothd,"mg_levels_");
244:     PetscLogObjectParent(pc,mg[l]->smoothu);
245:   }
246:   if (ksp) *ksp = mg[l]->smoothu;
247:   return(0);
248: }

252: /*@C
253:    MGGetSmootherDown - Gets the KSP context to be used as smoother before 
254:    coarse grid correction (pre-smoother). 

256:    Not Collective, KSP returned is parallel if PC is

258:    Input Parameters:
259: +  pc - the multigrid context 
260: -  l  - the level (0 is coarsest) to supply

262:    Ouput Parameters:
263: .  ksp - the smoother

265:    Level: advanced

267: .keywords: MG, multigrid, get, smoother, down, pre-smoother, level

269: .seealso: MGGetSmootherUp(), MGGetSmoother()
270: @*/
271: int MGGetSmootherDown(PC pc,int l,KSP *ksp)
272: {
274:   MG  *mg = (MG*)pc->data;

277:   /* make sure smoother up and down are different */
278:   MGGetSmootherUp(pc,l,PETSC_NULL);
279:   *ksp = mg[l]->smoothd;
280:   return(0);
281: }

285: /*@
286:    MGSetCyclesOnLevel - Sets the number of cycles to run on this level. 

288:    Collective on PC

290:    Input Parameters:
291: +  pc - the multigrid context 
292: .  l  - the level (0 is coarsest) this is to be used for
293: -  n  - the number of cycles

295:    Level: advanced

297: .keywords: MG, multigrid, set, cycles, V-cycle, W-cycle, level

299: .seealso: MGSetCycles()
300: @*/
301: int MGSetCyclesOnLevel(PC pc,int l,int c)
302: {
303:   MG *mg = (MG*)pc->data;

306:   if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
307:   mg[l]->cycles  = c;
308:   return(0);
309: }

313: /*@
314:    MGSetRhs - Sets the vector space to be used to store the right-hand side
315:    on a particular level.  The user should free this space at the conclusion 
316:    of multigrid use. 

318:    Collective on PC and Vec

320:    Input Parameters:
321: +  pc - the multigrid context 
322: .  l  - the level (0 is coarsest) this is to be used for
323: -  c  - the space

325:    Level: advanced

327: .keywords: MG, multigrid, set, right-hand-side, rhs, level

329: .seealso: MGSetX(), MGSetR()
330: @*/
331: int MGSetRhs(PC pc,int l,Vec c)
332: {
333:   MG *mg = (MG*)pc->data;

336:   if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
337:   mg[l]->b  = c;
338:   return(0);
339: }

343: /*@
344:    MGSetX - Sets the vector space to be used to store the solution on a 
345:    particular level.  The user should free this space at the conclusion 
346:    of multigrid use.

348:    Collective on PC and Vec

350:    Input Parameters:
351: +  pc - the multigrid context 
352: .  l - the level (0 is coarsest) this is to be used for
353: -  c - the space

355:    Level: advanced

357: .keywords: MG, multigrid, set, solution, level

359: .seealso: MGSetRhs(), MGSetR()
360: @*/
361: int MGSetX(PC pc,int l,Vec c)
362: {
363:   MG *mg = (MG*)pc->data;

366:   if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
367:   mg[l]->x  = c;
368:   return(0);
369: }

373: /*@
374:    MGSetR - Sets the vector space to be used to store the residual on a
375:    particular level.  The user should free this space at the conclusion of
376:    multigrid use.

378:    Collective on PC and Vec

380:    Input Parameters:
381: +  pc - the multigrid context 
382: .  l - the level (0 is coarsest) this is to be used for
383: -  c - the space

385:    Level: advanced

387: .keywords: MG, multigrid, set, residual, level
388: @*/
389: int MGSetR(PC pc,int l,Vec c)
390: {
391:   MG *mg = (MG*)pc->data;

394:   if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
395:   mg[l]->r  = c;
396:   return(0);
397: }