Actual source code: mlInterface.c

  1: #ifdef PETSC_RCS_HEADER
  2: static char vcid[] = "$Id: mlInterface.c,v 1.1 1999/06/09 20:24:12 knepley Exp $";
  3: #endif
  4: /*
  5:    Defines the interface for the  multilevel preconditioner due to
  6:    Vivek Sarin for AIJ matrices.
  7: */
 8:  #include src/sles/pc/pcimpl.h
 9:  #include petscsnes.h
 10:  #include ml.h

 12: /*@C PCMultiLevelSetFields
 13:         This function sets the shape and test function fields for the
 14:   gradient operator. It must be called prior to PCSetUp().

 16:   Collective on PC

 18:   Input Parameters:
 19: + pc     - The preconditioner context
 20: . sField - The shape function field
 21: - tField - The test function field

 23:   Level: intermediate

 25: .keywords multilevel, fields
 26: .seealso PCMultiLevelSetGradientOperator, PCMultiLevelSetNonlinearIterate
 27: @*/
 28: int PCMultiLevelSetFields(PC pc, int sField, int tField)
 29: {
 30:   PC_Multilevel *ml;

 34:   ml = (PC_Multilevel *) pc->data;
 35:   ml->sField = sField;
 36:   ml->tField = tField;
 37:   return(0);
 38: }

 40: /*@C PCMultiLevelSetNonlinearIterate
 41:         This function sets the solution vector used in a Newton iteration. If
 42:   the inner solve is preconditioned with ML, the current iterate is
 43:   necessary to perform the reduction of the system.

 45:   Collective on PC

 47:   Input Parameters:
 48: + pc - The preconditioner context
 49: - u  - The current iterate in a Newton solve

 51:   Level: intermediate

 53: .keywords multilevel, nonlinear
 54: .seealso PCMultiLevelSetFields, PCMultiLevelSetGradientOperator
 55: @*/
 56: int PCMultiLevelSetNonlinearIterate(PC pc, GVec u)
 57: {
 58:   PC_Multilevel *ml;

 63:   ml = (PC_Multilevel *) pc->data;
 64:   ml->nonlinearIterate = u;
 65:   return(0);
 66: }

 68: /*@C PCMultiLevelSetGradientOperator
 69:         This function sets the operator to use as the gradient and its transpose
 70:   in the multilevel scheme. It must be called prior to PCSetUp().

 72:   Collective on PC

 74:   Input Parameters:
 75: + pc    - The preconditioner context
 76: . grad  - The gradient operator
 77: . div   - The divergence operator
 78: - alpha - The scalar multiplier for the gradient operator

 80:   Level: intermediate

 82: .keywords multilevel, operator
 83: .seealso PCMultiLevelSetFields, PCMultiLevelSetNonlinearIterate
 84: @*/
 85: int PCMultiLevelSetGradientOperator(PC pc, int Grad, int Div, PetscScalar alpha)
 86: {
 87:   PC_Multilevel *ml;

 91:   ml = (PC_Multilevel *) pc->data;
 92:   ml->gradOp    = Grad;
 93:   ml->divOp     = Div;
 94:   ml->gradAlpha = alpha;
 95:   return(0);
 96: }

 98: /*@C PCMultiLevelBuildSolution
 99:         This function recovers the solution of the global problem
100:   from the solution of the reduced system.

102:   Collective on GVec

104:   Input Parameters:
105: + pc - The preconditioner context
106: - u  - The solution of the reduced system

108:   Output Parameter:
109: . u  - The global solution

111:   Level: beginner

113: .keywords multilevel, solution
114: .seealso PCMultiLevelApplyGradientGetMultiplier
115: @*/
116: int PCMultiLevelBuildSolution(PC pc, GVec u)
117: {
118:   PC_Multilevel *ml;
119:   Grid           grid;
120:   PetscScalar    alpha;
121:   int            ierr;

126:   if (pc->setupcalled < 2) {
127:     PCSetUp(pc);
128:   }

130:   ml = (PC_Multilevel *) pc->data;
131:   if (ml->reduceSol != PETSC_NULL) {
132:     ierr  = GVecGetGrid(u, &grid);
133:     ierr  = GridGetBCMultiplier(grid, &alpha);
134:     alpha = -alpha;
135:     ierr  = VecAXPY(&alpha, ml->reduceSol, u);
136:   }
137:   return(0);
138: }

140: /*@C PCMultiLevelBukldSolution
141:         This function recovers the multiplier of the global problem
142:   from the solution of the reduced system.

144:   Collective on GVec

146:   Input Parameters:
147: + pc - The preconditioner context
148: - u  - The solution of the reduced system

150:   Output Parameter:
151: . p  - The global multiplier

153:   Level: beginner

155: .keywords multilevel, solution, multiplier
156: .seealso PCMultiLevelBuildSolution
157: @*/
158: int PCMultiLevelGetMultiplier(PC pc, GVec u, GVec p)
159: {
160:   GVec        tempVec;
161:   PetscScalar minusOne = -1.0;
162:   PetscScalar zero     =  0.0;
163:   int         ierr;

169:   if ((pc->vec == PETSC_NULL) || (pc->mat == PETSC_NULL)) {
170:     VecSet(&zero, p);
171:     return(0);
172:   }
173:   if (pc->setupcalled < 2) {
174:     PCSetUp(pc);
175:   }

177:   /* Multiply P_2 (P^{-1} u)_2 by A */
178:   GVecDuplicate(u, &tempVec);
179:   MatMult(pc->mat, u, tempVec);

181:   /* Let A P_2 (P^{-1} u)_2 = f - A P_1 D^{-1} Z^T g - A P_2 (P^{-1} u)_2 --
182:        This is really unstaisfactory, but how do I get the Rhs after solution of
183:        the system. Perhaps I should have a flag for storing the multiplier.
184:   */
185:   VecAYPX(&minusOne, pc->vec, tempVec);

187:   /* Apply P^T_1 */
188:   PCMultiLevelApplyP1Trans(pc, tempVec, p);

190:   /* Apply Z D^{-1} */
191:   PCMultiLevelApplyDInv(pc, p, p);
192:   PCMultiLevelApplyV(pc, p, p);

194:   /* Cleanup */
195:   VecDestroy(tempVec);
196:   return(0);
197: }