Actual source code: galerkin.c
 
   petsc-3.6.2 2015-10-02
   
  2: /*
  3:       Defines a preconditioner defined by R^T S R
  4: */
  5: #include <petsc/private/pcimpl.h>
  6: #include <petscksp.h>         /*I "petscksp.h" I*/
  8: typedef struct {
  9:   KSP ksp;
 10:   Mat R,P;
 11:   Vec b,x;
 12: } PC_Galerkin;
 16: static PetscErrorCode PCApply_Galerkin(PC pc,Vec x,Vec y)
 17: {
 19:   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
 22:   if (jac->R) {
 23:     MatRestrict(jac->R,x,jac->b);
 24:   } else {
 25:     MatRestrict(jac->P,x,jac->b);
 26:   }
 27:   KSPSolve(jac->ksp,jac->b,jac->x);
 28:   if (jac->P) {
 29:     MatInterpolate(jac->P,jac->x,y);
 30:   } else {
 31:     MatInterpolate(jac->R,jac->x,y);
 32:   }
 33:   return(0);
 34: }
 38: static PetscErrorCode PCSetUp_Galerkin(PC pc)
 39: {
 41:   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
 42:   PetscBool      a;
 43:   Vec            *xx,*yy;
 46:   if (!jac->x) {
 47:     KSPGetOperatorsSet(jac->ksp,&a,NULL);
 48:     if (!a) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set operator of PCGALERKIN KSP with PCGalerkinGetKSP()/KSPSetOperators()");
 49:     KSPCreateVecs(jac->ksp,1,&xx,1,&yy);
 50:     jac->x = *xx;
 51:     jac->b = *yy;
 52:     PetscFree(xx);
 53:     PetscFree(yy);
 54:   }
 55:   if (!jac->R && !jac->P) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set restriction or interpolation of PCGALERKIN with PCGalerkinSetRestriction/Interpolation()");
 56:   /* should check here that sizes of R/P match size of a */
 57:   return(0);
 58: }
 62: static PetscErrorCode PCReset_Galerkin(PC pc)
 63: {
 64:   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
 68:   MatDestroy(&jac->R);
 69:   MatDestroy(&jac->P);
 70:   VecDestroy(&jac->x);
 71:   VecDestroy(&jac->b);
 72:   KSPReset(jac->ksp);
 73:   return(0);
 74: }
 78: static PetscErrorCode PCDestroy_Galerkin(PC pc)
 79: {
 80:   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
 84:   PCReset_Galerkin(pc);
 85:   KSPDestroy(&jac->ksp);
 86:   PetscFree(pc->data);
 87:   return(0);
 88: }
 92: static PetscErrorCode PCView_Galerkin(PC pc,PetscViewer viewer)
 93: {
 94:   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
 96:   PetscBool      iascii;
 99:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
100:   if (iascii) {
101:     PetscViewerASCIIPrintf(viewer,"Galerkin PC\n");
102:     PetscViewerASCIIPrintf(viewer,"KSP on Galerkin follow\n");
103:     PetscViewerASCIIPrintf(viewer,"---------------------------------\n");
104:   }
105:   KSPView(jac->ksp,viewer);
106:   return(0);
107: }
111: static PetscErrorCode  PCGalerkinGetKSP_Galerkin(PC pc,KSP *ksp)
112: {
113:   PC_Galerkin *jac = (PC_Galerkin*)pc->data;
116:   *ksp = jac->ksp;
117:   return(0);
118: }
122: static PetscErrorCode  PCGalerkinSetRestriction_Galerkin(PC pc,Mat R)
123: {
124:   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
128:   PetscObjectReference((PetscObject)R);
129:   MatDestroy(&jac->R);
130:   jac->R = R;
131:   return(0);
132: }
136: static PetscErrorCode  PCGalerkinSetInterpolation_Galerkin(PC pc,Mat P)
137: {
138:   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
142:   PetscObjectReference((PetscObject)P);
143:   MatDestroy(&jac->P);
144:   jac->P = P;
145:   return(0);
146: }
148: /* -------------------------------------------------------------------------------- */
151: /*@
152:    PCGalerkinSetRestriction - Sets the restriction operator for the "Galerkin-type" preconditioner
154:    Logically Collective on PC
156:    Input Parameter:
157: +  pc - the preconditioner context
158: -  R - the restriction operator
160:    Notes: Either this or PCGalerkinSetInterpolation() or both must be called
162:    Level: Intermediate
164: .keywords: PC, set, Galerkin preconditioner
166: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
167:            PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
169: @*/
170: PetscErrorCode  PCGalerkinSetRestriction(PC pc,Mat R)
171: {
176:   PetscTryMethod(pc,"PCGalerkinSetRestriction_C",(PC,Mat),(pc,R));
177:   return(0);
178: }
182: /*@
183:    PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner
185:    Logically Collective on PC
187:    Input Parameter:
188: +  pc - the preconditioner context
189: -  R - the interpolation operator
191:    Notes: Either this or PCGalerkinSetRestriction() or both must be called
193:    Level: Intermediate
195: .keywords: PC, set, Galerkin preconditioner
197: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
198:            PCGalerkinSetRestriction(), PCGalerkinGetKSP()
200: @*/
201: PetscErrorCode  PCGalerkinSetInterpolation(PC pc,Mat P)
202: {
207:   PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));
208:   return(0);
209: }
213: /*@
214:    PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC.
216:    Not Collective
218:    Input Parameter:
219: .  pc - the preconditioner context
221:    Output Parameters:
222: .  ksp - the KSP object
224:    Level: Intermediate
226: .keywords: PC, get, Galerkin preconditioner, sub preconditioner
228: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
229:            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation()
231: @*/
232: PetscErrorCode  PCGalerkinGetKSP(PC pc,KSP *ksp)
233: {
239:   PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));
240:   return(0);
241: }
244: /* -------------------------------------------------------------------------------------------*/
246: /*MC
247:      PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T)
249: $   Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by
250: $   PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....)
252:    Level: intermediate
254:    Developer Note: If KSPSetOperators() has not been called then PCGALERKIN could use MatRARt() or MatPtAP() to compute
255:                    the operators automatically.
256:                    Should there be a prefix for the inner KSP.
257:                    There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP
259: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
260:            PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
262: M*/
266: PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc)
267: {
269:   PC_Galerkin    *jac;
272:   PetscNewLog(pc,&jac);
274:   pc->ops->apply           = PCApply_Galerkin;
275:   pc->ops->setup           = PCSetUp_Galerkin;
276:   pc->ops->reset           = PCReset_Galerkin;
277:   pc->ops->destroy         = PCDestroy_Galerkin;
278:   pc->ops->view            = PCView_Galerkin;
279:   pc->ops->applyrichardson = 0;
281:   KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp);
282:   KSPSetErrorIfNotConverged(jac->ksp,pc->erroriffailure);
283:   PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);
285:   pc->data = (void*)jac;
287:   PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin);
288:   PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin);
289:   PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin);
290:   return(0);
291: }