Actual source code: fmg.c

  1: /*
  2:      Full multigrid using either additive or multiplicative V or W cycle
  3: */
 4:  #include src/ksp/pc/impls/mg/mgimpl.h

  6: EXTERN PetscErrorCode MGMCycle_Private(MG *,PetscTruth*);

  8: /*
  9:        MGFCycle_Private - Given an MG structure created with MGCreate() runs 
 10:                full multigrid. 

 12:     Iput Parameters:
 13: .   mg - structure created with MGCreate().

 15:     Note: This may not be what others call full multigrid. What we
 16:           do is restrict the rhs to all levels, then starting 
 17:           on the coarsest level work our way up generating 
 18:           initial guess for the next level. This provides an
 19:           improved preconditioner but not a great improvement.
 20: */
 23: PetscErrorCode MGFCycle_Private(MG *mg)
 24: {
 26:   PetscInt       i,l = mg[0]->levels;
 27:   PetscScalar    zero = 0.0;

 30:   /* restrict the RHS through all levels to coarsest. */
 31:   for (i=l-1; i>0; i--){
 32:     MatRestrict(mg[i]->restrct,mg[i]->b,mg[i-1]->b);
 33:   }
 34: 
 35:   /* work our way up through the levels */
 36:   VecSet(&zero,mg[0]->x);
 37:   for (i=0; i<l-1; i++) {
 38:     MGMCycle_Private(&mg[i],PETSC_NULL);
 39:     MatInterpolate(mg[i+1]->interpolate,mg[i]->x,mg[i+1]->x);
 40:   }
 41:   MGMCycle_Private(&mg[l-1],PETSC_NULL);
 42:   return(0);
 43: }

 45: /*
 46:        MGKCycle_Private - Given an MG structure created with MGCreate() runs 
 47:                full Kascade MG solve.

 49:     Iput Parameters:
 50: .   mg - structure created with MGCreate().

 52:     Note: This may not be what others call Kascadic MG.
 53: */
 56: PetscErrorCode MGKCycle_Private(MG *mg)
 57: {
 59:   PetscInt       i,l = mg[0]->levels;
 60:   PetscScalar    zero = 0.0;

 63:   /* restrict the RHS through all levels to coarsest. */
 64:   for (i=l-1; i>0; i--){
 65:     MatRestrict(mg[i]->restrct,mg[i]->b,mg[i-1]->b);
 66:   }
 67: 
 68:   /* work our way up through the levels */
 69:   VecSet(&zero,mg[0]->x);
 70:   for (i=0; i<l-1; i++) {
 71:     if (mg[i]->eventsolve) {PetscLogEventBegin(mg[i]->eventsolve,0,0,0,0);}
 72:     KSPSolve(mg[i]->smoothd,mg[i]->b,mg[i]->x);
 73:     if (mg[i]->eventsolve) {PetscLogEventEnd(mg[i]->eventsolve,0,0,0,0);}
 74:     MatInterpolate(mg[i+1]->interpolate,mg[i]->x,mg[i+1]->x);
 75:   }
 76:   if (mg[l-1]->eventsolve) {PetscLogEventBegin(mg[l-1]->eventsolve,0,0,0,0);}
 77:   KSPSolve(mg[l-1]->smoothd,mg[l-1]->b,mg[l-1]->x);
 78:   if (mg[l-1]->eventsolve) {PetscLogEventEnd(mg[l-1]->eventsolve,0,0,0,0);}

 80:   return(0);
 81: }