Actual source code: mgfunc.c

 2:  #include src/ksp/pc/impls/mg/mgimpl.h
  3:                           /*I "petscmg.h"   I*/

  7: /*@C
  8:    MGDefaultResidual - Default routine to calculate the residual.

 10:    Collective on Mat and Vec

 12:    Input Parameters:
 13: +  mat - the matrix
 14: .  b   - the right-hand-side
 15: -  x   - the approximate solution
 16:  
 17:    Output Parameter:
 18: .  r - location to store the residual

 20:    Level: advanced

 22: .keywords: MG, default, multigrid, residual

 24: .seealso: MGSetResidual()
 25: @*/
 26: PetscErrorCode MGDefaultResidual(Mat mat,Vec b,Vec x,Vec r)
 27: {
 29:   PetscScalar    mone = -1.0;

 32:   MatMult(mat,x,r);
 33:   VecAYPX(&mone,b,r);
 34:   return(0);
 35: }

 37: /* ---------------------------------------------------------------------------*/

 41: /*@C
 42:    MGGetCoarseSolve - 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 MGGetCoarseSolve(PC pc,KSP *ksp)
 57: {
 58:   MG *mg = (MG*)pc->data;

 61:   *ksp =  mg[0]->smoothd;
 62:   return(0);
 63: }

 67: /*@C
 68:    MGSetResidual - 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 MGDefaultResidual)
 77: -  mat      - matrix associated with residual

 79:    Level: advanced

 81: .keywords:  MG, set, multigrid, residual, level

 83: .seealso: MGDefaultResidual()
 84: @*/
 85: PetscErrorCode MGSetResidual(PC pc,PetscInt l,PetscErrorCode (*residual)(Mat,Vec,Vec,Vec),Mat mat)
 86: {
 87:   MG *mg = (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:    MGSetInterpolate - 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: .keywords:  multigrid, set, interpolate, level

121: .seealso: MGSetRestriction()
122: @*/
123: PetscErrorCode MGSetInterpolate(PC pc,PetscInt l,Mat mat)
124: {
125:   MG *mg = (MG*)pc->data;

128:   if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
129:   mg[l]->interpolate = mat;
130:   return(0);
131: }

135: /*@
136:    MGSetRestriction - Sets the function to be used to restrict vector
137:    from level l to l-1. 

139:    Collective on PC and Mat

141:    Input Parameters:
142: +  pc - the multigrid context 
143: .  mat - the restriction matrix
144: -  l - the level (0 is coarsest) to supply

146:    Level: advanced

148:    Notes: 
149:           Usually this is the same matrix used also to set the interpolation
150:     for the same level.

152:           One can pass in the interpolation matrix or its transpose; PETSc figures
153:     out from the matrix size which one it is.

155: .keywords: MG, set, multigrid, restriction, level

157: .seealso: MGSetInterpolate()
158: @*/
159: PetscErrorCode MGSetRestriction(PC pc,PetscInt l,Mat mat)
160: {
161:   MG *mg = (MG*)pc->data;

164:   if (!mg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling");
165:   mg[l]->restrct  = mat;
166:   return(0);
167: }

171: /*@C
172:    MGGetSmoother - Gets the KSP context to be used as smoother for 
173:    both pre- and post-smoothing.  Call both MGGetSmootherUp() and 
174:    MGGetSmootherDown() to use different functions for pre- and 
175:    post-smoothing.

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

179:    Input Parameters:
180: +  pc - the multigrid context 
181: -  l - the level (0 is coarsest) to supply

183:    Ouput Parameters:
184: .  ksp - the smoother

186:    Level: advanced

188: .keywords: MG, get, multigrid, level, smoother, pre-smoother, post-smoother

190: .seealso: MGGetSmootherUp(), MGGetSmootherDown()
191: @*/
192: PetscErrorCode MGGetSmoother(PC pc,PetscInt l,KSP *ksp)
193: {
194:   MG *mg = (MG*)pc->data;

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

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

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

209:    Input Parameters:
210: +  pc - the multigrid context 
211: -  l  - the level (0 is coarsest) to supply

213:    Ouput Parameters:
214: .  ksp - the smoother

216:    Level: advanced

218: .keywords: MG, multigrid, get, smoother, up, post-smoother, level

220: .seealso: MGGetSmootherUp(), MGGetSmootherDown()
221: @*/
222: PetscErrorCode MGGetSmootherUp(PC pc,PetscInt l,KSP *ksp)
223: {
224:   MG             *mg = (MG*)pc->data;
226:   char           *prefix;
227:   MPI_Comm       comm;

230:   /*
231:      This is called only if user wants a different pre-smoother from post.
232:      Thus we check if a different one has already been allocated, 
233:      if not we allocate it.
234:   */

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

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

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

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

260:    Ouput Parameters:
261: .  ksp - the smoother

263:    Level: advanced

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

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

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

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

286:    Collective on PC

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

293:    Level: advanced

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

297: .seealso: MGSetCycles()
298: @*/
299: PetscErrorCode MGSetCyclesOnLevel(PC pc,PetscInt l,PetscInt c)
300: {
301:   MG *mg = (MG*)pc->data;

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

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

316:    Collective on PC and Vec

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

323:    Level: advanced

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

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

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

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

346:    Collective on PC and Vec

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

353:    Level: advanced

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

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

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

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

376:    Collective on PC and Vec

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

383:    Level: advanced

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

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