xref: /petsc/src/ksp/pc/impls/galerkin/galerkin.c (revision b3402f20833ac8b8803317cf445f0ec252f9070a)
12a6744ebSBarry Smith 
22a6744ebSBarry Smith /*
32a6744ebSBarry Smith       Defines a preconditioner defined by R^T S R
42a6744ebSBarry Smith */
5af0996ceSBarry Smith #include <petsc/private/pcimpl.h>
6c6db04a5SJed Brown #include <petscksp.h>         /*I "petscksp.h" I*/
72a6744ebSBarry Smith 
82a6744ebSBarry Smith typedef struct {
92a6744ebSBarry Smith   KSP            ksp;
102a6744ebSBarry Smith   Mat            R,P;
112a6744ebSBarry Smith   Vec            b,x;
12*b3402f20SBarry Smith   PetscErrorCode (*computeasub)(PC,Mat,Mat,Mat*,void*);
13*b3402f20SBarry Smith   void           *computeasub_ctx;
142a6744ebSBarry Smith } PC_Galerkin;
152a6744ebSBarry Smith 
162a6744ebSBarry Smith static PetscErrorCode PCApply_Galerkin(PC pc,Vec x,Vec y)
172a6744ebSBarry Smith {
182a6744ebSBarry Smith   PetscErrorCode ierr;
192a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
202a6744ebSBarry Smith 
212a6744ebSBarry Smith   PetscFunctionBegin;
222fa5cd67SKarl Rupp   if (jac->R) {
232fa5cd67SKarl Rupp     ierr = MatRestrict(jac->R,x,jac->b);CHKERRQ(ierr);
242fa5cd67SKarl Rupp   } else {
252fa5cd67SKarl Rupp     ierr = MatRestrict(jac->P,x,jac->b);CHKERRQ(ierr);
262fa5cd67SKarl Rupp   }
272a6744ebSBarry Smith   ierr = KSPSolve(jac->ksp,jac->b,jac->x);CHKERRQ(ierr);
282fa5cd67SKarl Rupp   if (jac->P) {
292fa5cd67SKarl Rupp     ierr = MatInterpolate(jac->P,jac->x,y);CHKERRQ(ierr);
302fa5cd67SKarl Rupp   } else {
312fa5cd67SKarl Rupp     ierr = MatInterpolate(jac->R,jac->x,y);CHKERRQ(ierr);
322fa5cd67SKarl Rupp   }
332a6744ebSBarry Smith   PetscFunctionReturn(0);
342a6744ebSBarry Smith }
352a6744ebSBarry Smith 
362a6744ebSBarry Smith static PetscErrorCode PCSetUp_Galerkin(PC pc)
372a6744ebSBarry Smith {
382a6744ebSBarry Smith   PetscErrorCode ierr;
392a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
40ace3abfcSBarry Smith   PetscBool      a;
41906ed7ccSBarry Smith   Vec            *xx,*yy;
422a6744ebSBarry Smith 
432a6744ebSBarry Smith   PetscFunctionBegin;
44*b3402f20SBarry Smith   if (jac->computeasub) {
45*b3402f20SBarry Smith     Mat Ap;
46*b3402f20SBarry Smith     if (!pc->setupcalled) {
47*b3402f20SBarry Smith       ierr = (*jac->computeasub)(pc,pc->pmat,NULL,&Ap,jac->computeasub_ctx);CHKERRQ(ierr);
48*b3402f20SBarry Smith       ierr = KSPSetOperators(jac->ksp,Ap,Ap);CHKERRQ(ierr);
49*b3402f20SBarry Smith       ierr = MatDestroy(&Ap);CHKERRQ(ierr);
50*b3402f20SBarry Smith     } else {
51*b3402f20SBarry Smith       ierr = KSPGetOperators(jac->ksp,NULL,&Ap);CHKERRQ(ierr);
52*b3402f20SBarry Smith       ierr = (*jac->computeasub)(pc,pc->pmat,Ap,NULL,jac->computeasub_ctx);CHKERRQ(ierr);
53*b3402f20SBarry Smith     }
54*b3402f20SBarry Smith   }
55*b3402f20SBarry Smith 
562a6744ebSBarry Smith   if (!jac->x) {
570298fd71SBarry Smith     ierr = KSPGetOperatorsSet(jac->ksp,&a,NULL);CHKERRQ(ierr);
58ce94432eSBarry Smith     if (!a) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set operator of PCGALERKIN KSP with PCGalerkinGetKSP()/KSPSetOperators()");
592a7a6963SBarry Smith     ierr   = KSPCreateVecs(jac->ksp,1,&xx,1,&yy);CHKERRQ(ierr);
60906ed7ccSBarry Smith     jac->x = *xx;
61906ed7ccSBarry Smith     jac->b = *yy;
62906ed7ccSBarry Smith     ierr   = PetscFree(xx);CHKERRQ(ierr);
63906ed7ccSBarry Smith     ierr   = PetscFree(yy);CHKERRQ(ierr);
642a6744ebSBarry Smith   }
654ac220ccSBarry Smith   if (!jac->R && !jac->P) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set restriction or interpolation of PCGALERKIN with PCGalerkinSetRestriction()/Interpolation()");
662a6744ebSBarry Smith   /* should check here that sizes of R/P match size of a */
67*b3402f20SBarry Smith 
682a6744ebSBarry Smith   PetscFunctionReturn(0);
692a6744ebSBarry Smith }
702a6744ebSBarry Smith 
71a06653b4SBarry Smith static PetscErrorCode PCReset_Galerkin(PC pc)
722a6744ebSBarry Smith {
732a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
742a6744ebSBarry Smith   PetscErrorCode ierr;
752a6744ebSBarry Smith 
762a6744ebSBarry Smith   PetscFunctionBegin;
776bf464f9SBarry Smith   ierr = MatDestroy(&jac->R);CHKERRQ(ierr);
786bf464f9SBarry Smith   ierr = MatDestroy(&jac->P);CHKERRQ(ierr);
796bf464f9SBarry Smith   ierr = VecDestroy(&jac->x);CHKERRQ(ierr);
806bf464f9SBarry Smith   ierr = VecDestroy(&jac->b);CHKERRQ(ierr);
81a06653b4SBarry Smith   ierr = KSPReset(jac->ksp);CHKERRQ(ierr);
82a06653b4SBarry Smith   PetscFunctionReturn(0);
83a06653b4SBarry Smith }
84a06653b4SBarry Smith 
85a06653b4SBarry Smith static PetscErrorCode PCDestroy_Galerkin(PC pc)
86a06653b4SBarry Smith {
87a06653b4SBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
88a06653b4SBarry Smith   PetscErrorCode ierr;
89a06653b4SBarry Smith 
90a06653b4SBarry Smith   PetscFunctionBegin;
91fcfd50ebSBarry Smith   ierr = PCReset_Galerkin(pc);CHKERRQ(ierr);
926bf464f9SBarry Smith   ierr = KSPDestroy(&jac->ksp);CHKERRQ(ierr);
93c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
942a6744ebSBarry Smith   PetscFunctionReturn(0);
952a6744ebSBarry Smith }
962a6744ebSBarry Smith 
972a6744ebSBarry Smith static PetscErrorCode PCView_Galerkin(PC pc,PetscViewer viewer)
982a6744ebSBarry Smith {
992a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1002a6744ebSBarry Smith   PetscErrorCode ierr;
101ace3abfcSBarry Smith   PetscBool      iascii;
1022a6744ebSBarry Smith 
1032a6744ebSBarry Smith   PetscFunctionBegin;
104251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1052a6744ebSBarry Smith   if (iascii) {
1062a6744ebSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Galerkin PC\n");CHKERRQ(ierr);
1072a6744ebSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"KSP on Galerkin follow\n");CHKERRQ(ierr);
1082a6744ebSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr);
1092a6744ebSBarry Smith   }
1102a6744ebSBarry Smith   ierr = KSPView(jac->ksp,viewer);CHKERRQ(ierr);
1112a6744ebSBarry Smith   PetscFunctionReturn(0);
1122a6744ebSBarry Smith }
1132a6744ebSBarry Smith 
1141e6b0712SBarry Smith static PetscErrorCode  PCGalerkinGetKSP_Galerkin(PC pc,KSP *ksp)
1152a6744ebSBarry Smith {
1162a6744ebSBarry Smith   PC_Galerkin *jac = (PC_Galerkin*)pc->data;
1172a6744ebSBarry Smith 
1182a6744ebSBarry Smith   PetscFunctionBegin;
1192a6744ebSBarry Smith   *ksp = jac->ksp;
1202a6744ebSBarry Smith   PetscFunctionReturn(0);
1212a6744ebSBarry Smith }
1222a6744ebSBarry Smith 
1231e6b0712SBarry Smith static PetscErrorCode  PCGalerkinSetRestriction_Galerkin(PC pc,Mat R)
1242a6744ebSBarry Smith {
1252a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1262a6744ebSBarry Smith   PetscErrorCode ierr;
1272a6744ebSBarry Smith 
1282a6744ebSBarry Smith   PetscFunctionBegin;
129c3122656SLisandro Dalcin   ierr   = PetscObjectReference((PetscObject)R);CHKERRQ(ierr);
1306bf464f9SBarry Smith   ierr   = MatDestroy(&jac->R);CHKERRQ(ierr);
1312a6744ebSBarry Smith   jac->R = R;
1322a6744ebSBarry Smith   PetscFunctionReturn(0);
1332a6744ebSBarry Smith }
1342a6744ebSBarry Smith 
1351e6b0712SBarry Smith static PetscErrorCode  PCGalerkinSetInterpolation_Galerkin(PC pc,Mat P)
1362a6744ebSBarry Smith {
1372a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1382a6744ebSBarry Smith   PetscErrorCode ierr;
1392a6744ebSBarry Smith 
1402a6744ebSBarry Smith   PetscFunctionBegin;
141c3122656SLisandro Dalcin   ierr   = PetscObjectReference((PetscObject)P);CHKERRQ(ierr);
1426bf464f9SBarry Smith   ierr   = MatDestroy(&jac->P);CHKERRQ(ierr);
1432a6744ebSBarry Smith   jac->P = P;
1442a6744ebSBarry Smith   PetscFunctionReturn(0);
1452a6744ebSBarry Smith }
1462a6744ebSBarry Smith 
147*b3402f20SBarry Smith static PetscErrorCode  PCGalerkinSetComputeSubmatrix_Galerkin(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx)
148*b3402f20SBarry Smith {
149*b3402f20SBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
150*b3402f20SBarry Smith 
151*b3402f20SBarry Smith   PetscFunctionBegin;
152*b3402f20SBarry Smith   jac->computeasub     = computeAsub;
153*b3402f20SBarry Smith   jac->computeasub_ctx = ctx;
154*b3402f20SBarry Smith   PetscFunctionReturn(0);
155*b3402f20SBarry Smith }
156*b3402f20SBarry Smith 
1572a6744ebSBarry Smith /* -------------------------------------------------------------------------------- */
1582a6744ebSBarry Smith /*@
1592a6744ebSBarry Smith    PCGalerkinSetRestriction - Sets the restriction operator for the "Galerkin-type" preconditioner
1602a6744ebSBarry Smith 
161ad4df100SBarry Smith    Logically Collective on PC
1622a6744ebSBarry Smith 
1632a6744ebSBarry Smith    Input Parameter:
1642a6744ebSBarry Smith +  pc - the preconditioner context
1652a6744ebSBarry Smith -  R - the restriction operator
1662a6744ebSBarry Smith 
1672a6744ebSBarry Smith    Notes: Either this or PCGalerkinSetInterpolation() or both must be called
1682a6744ebSBarry Smith 
1692a6744ebSBarry Smith    Level: Intermediate
1702a6744ebSBarry Smith 
1712a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
1722a6744ebSBarry Smith 
1732a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
1742a6744ebSBarry Smith            PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
1752a6744ebSBarry Smith 
1762a6744ebSBarry Smith @*/
1777087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetRestriction(PC pc,Mat R)
1782a6744ebSBarry Smith {
1794ac538c5SBarry Smith   PetscErrorCode ierr;
1802a6744ebSBarry Smith 
1812a6744ebSBarry Smith   PetscFunctionBegin;
1820700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1834ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetRestriction_C",(PC,Mat),(pc,R));CHKERRQ(ierr);
1842a6744ebSBarry Smith   PetscFunctionReturn(0);
1852a6744ebSBarry Smith }
1862a6744ebSBarry Smith 
1872a6744ebSBarry Smith /*@
1882a6744ebSBarry Smith    PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner
1892a6744ebSBarry Smith 
190ad4df100SBarry Smith    Logically Collective on PC
1912a6744ebSBarry Smith 
1922a6744ebSBarry Smith    Input Parameter:
1932a6744ebSBarry Smith +  pc - the preconditioner context
1942a6744ebSBarry Smith -  R - the interpolation operator
1952a6744ebSBarry Smith 
1962a6744ebSBarry Smith    Notes: Either this or PCGalerkinSetRestriction() or both must be called
1972a6744ebSBarry Smith 
1982a6744ebSBarry Smith    Level: Intermediate
1992a6744ebSBarry Smith 
2002a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
2012a6744ebSBarry Smith 
2022a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
2032a6744ebSBarry Smith            PCGalerkinSetRestriction(), PCGalerkinGetKSP()
2042a6744ebSBarry Smith 
2052a6744ebSBarry Smith @*/
2067087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetInterpolation(PC pc,Mat P)
2072a6744ebSBarry Smith {
2084ac538c5SBarry Smith   PetscErrorCode ierr;
2092a6744ebSBarry Smith 
2102a6744ebSBarry Smith   PetscFunctionBegin;
2110700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2124ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));CHKERRQ(ierr);
2132a6744ebSBarry Smith   PetscFunctionReturn(0);
2142a6744ebSBarry Smith }
2152a6744ebSBarry Smith 
2162a6744ebSBarry Smith /*@
217*b3402f20SBarry Smith    PCGalerkinSetComputeSubmatrix - Provide a routine that will be called to compute the Galerkin submatrix
218*b3402f20SBarry Smith 
219*b3402f20SBarry Smith    Logically Collective
220*b3402f20SBarry Smith 
221*b3402f20SBarry Smith    Input Parameter:
222*b3402f20SBarry Smith +  pc - the preconditioner context
223*b3402f20SBarry Smith .  computeAsub - routine that computes the submatrix from the global matrix
224*b3402f20SBarry Smith -  ctx - context used by the routine, or NULL
225*b3402f20SBarry Smith 
226*b3402f20SBarry Smith    Calling sequence of computeAsub:
227*b3402f20SBarry Smith $    computeAsub(PC pc,Mat A, Mat Ap, Mat *cAP,void *ctx);
228*b3402f20SBarry Smith 
229*b3402f20SBarry Smith +  PC - the Galerkin PC
230*b3402f20SBarry Smith .  A - the matrix in the Galerkin PC
231*b3402f20SBarry Smith .  Ap - the computed submatrix from any previous computation, if NULL it has not previously been computed
232*b3402f20SBarry Smith .  cAp - the submatrix computed by this routine
233*b3402f20SBarry Smith -  ctx - optional user-defined function context
234*b3402f20SBarry Smith 
235*b3402f20SBarry Smith    Level: Intermediate
236*b3402f20SBarry Smith 
237*b3402f20SBarry Smith    Notes: Instead of providing this routine you can call PCGalerkinGetKSP() and then KSPSetOperators() to provide the submatrix,
238*b3402f20SBarry Smith           but that will not work for multiple KSPSolves with different matrices unless you call it for each solve.
239*b3402f20SBarry Smith 
240*b3402f20SBarry Smith           This routine is called each time the outter matrix is changed. In the first call the Ap argument is NULL and the routine should create the
241*b3402f20SBarry Smith           matrix and computes its values in cAp. On each subsequent call the routine should up the Ap matrix.
242*b3402f20SBarry Smith 
243*b3402f20SBarry Smith    Developer Notes: If the user does not call this routine nor call PCGalerkinGetKSP() and KSPSetOperators() then PCGalerkin could
244*b3402f20SBarry Smith                     could automatically compute the submatrix via calls to MatGalerkin() or MatRARt()
245*b3402f20SBarry Smith 
246*b3402f20SBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner
247*b3402f20SBarry Smith 
248*b3402f20SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
249*b3402f20SBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
250*b3402f20SBarry Smith 
251*b3402f20SBarry Smith @*/
252*b3402f20SBarry Smith PetscErrorCode  PCGalerkinSetComputeSubmatrix(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx)
253*b3402f20SBarry Smith {
254*b3402f20SBarry Smith   PetscErrorCode ierr;
255*b3402f20SBarry Smith 
256*b3402f20SBarry Smith   PetscFunctionBegin;
257*b3402f20SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
258*b3402f20SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetComputeSubmatrix_C",(PC,PetscErrorCode (*)(PC,Mat,Mat,Mat*,void*),void*),(pc,computeAsub,ctx));CHKERRQ(ierr);
259*b3402f20SBarry Smith   PetscFunctionReturn(0);
260*b3402f20SBarry Smith }
261*b3402f20SBarry Smith 
262*b3402f20SBarry Smith /*@
2632a6744ebSBarry Smith    PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC.
2642a6744ebSBarry Smith 
2652a6744ebSBarry Smith    Not Collective
2662a6744ebSBarry Smith 
2672a6744ebSBarry Smith    Input Parameter:
2682a6744ebSBarry Smith .  pc - the preconditioner context
2692a6744ebSBarry Smith 
2702a6744ebSBarry Smith    Output Parameters:
2712a6744ebSBarry Smith .  ksp - the KSP object
2722a6744ebSBarry Smith 
2732a6744ebSBarry Smith    Level: Intermediate
2742a6744ebSBarry Smith 
275*b3402f20SBarry Smith    Notes: Once you have called this routine you can call KSPSetOperators() on the resulting ksp to provide the operator for the Galerkin problem,
276*b3402f20SBarry Smith           an alternative is to use PCGalerkinSetComputeSubmatrix() to provide a routine that computes the submatrix as needed.
277*b3402f20SBarry Smith 
2782a6744ebSBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner
2792a6744ebSBarry Smith 
2802a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
281*b3402f20SBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinSetComputeSubmatrix()
2822a6744ebSBarry Smith 
2832a6744ebSBarry Smith @*/
2847087cfbeSBarry Smith PetscErrorCode  PCGalerkinGetKSP(PC pc,KSP *ksp)
2852a6744ebSBarry Smith {
2864ac538c5SBarry Smith   PetscErrorCode ierr;
2872a6744ebSBarry Smith 
2882a6744ebSBarry Smith   PetscFunctionBegin;
2890700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2902a6744ebSBarry Smith   PetscValidPointer(ksp,2);
2914ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr);
2922a6744ebSBarry Smith   PetscFunctionReturn(0);
2932a6744ebSBarry Smith }
2942a6744ebSBarry Smith 
2954ac220ccSBarry Smith static PetscErrorCode PCSetFromOptions_Galerkin(PetscOptionItems *PetscOptionsObject,PC pc)
2964ac220ccSBarry Smith {
2974ac220ccSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
2984ac220ccSBarry Smith   PetscErrorCode ierr;
2994ac220ccSBarry Smith   const char     *prefix;
3004ac220ccSBarry Smith   PetscBool      flg;
3014ac220ccSBarry Smith 
3024ac220ccSBarry Smith   PetscFunctionBegin;
3034ac220ccSBarry Smith   ierr = KSPGetOptionsPrefix(jac->ksp,&prefix);CHKERRQ(ierr);
3044ac220ccSBarry Smith   ierr = PetscStrendswith(prefix,"galerkin_",&flg);CHKERRQ(ierr);
3054ac220ccSBarry Smith   if (!flg) {
3064ac220ccSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
3074ac220ccSBarry Smith     ierr = KSPSetOptionsPrefix(jac->ksp,prefix);CHKERRQ(ierr);
3084ac220ccSBarry Smith     ierr = KSPAppendOptionsPrefix(jac->ksp,"galerkin_");CHKERRQ(ierr);
3094ac220ccSBarry Smith   }
3104ac220ccSBarry Smith 
3114ac220ccSBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Galerkin options");CHKERRQ(ierr);
3124ac220ccSBarry Smith   if (jac->ksp) {
3134ac220ccSBarry Smith     ierr = KSPSetFromOptions(jac->ksp);CHKERRQ(ierr);
3144ac220ccSBarry Smith   }
3154ac220ccSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
3164ac220ccSBarry Smith   PetscFunctionReturn(0);
3174ac220ccSBarry Smith }
3182a6744ebSBarry Smith 
3192a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/
3202a6744ebSBarry Smith 
3212a6744ebSBarry Smith /*MC
3222a6744ebSBarry Smith      PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T)
3232a6744ebSBarry Smith 
3242a6744ebSBarry Smith $   Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by
3257817a140SBarry Smith $   PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....)
3262a6744ebSBarry Smith 
3272a6744ebSBarry Smith    Level: intermediate
3282a6744ebSBarry Smith 
329b59c8b46SBarry Smith    Developer Note: If KSPSetOperators() has not been called on the inner KSP then PCGALERKIN could use MatRARt() or MatPtAP() to compute
3307817a140SBarry Smith                    the operators automatically.
3317817a140SBarry Smith                    Should there be a prefix for the inner KSP.
3327817a140SBarry Smith                    There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP
3337817a140SBarry Smith 
3342a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
3352a6744ebSBarry Smith            PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
3362a6744ebSBarry Smith 
3372a6744ebSBarry Smith M*/
3382a6744ebSBarry Smith 
3398cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc)
3402a6744ebSBarry Smith {
3412a6744ebSBarry Smith   PetscErrorCode ierr;
3422a6744ebSBarry Smith   PC_Galerkin    *jac;
3432a6744ebSBarry Smith 
3442a6744ebSBarry Smith   PetscFunctionBegin;
345b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
3462fa5cd67SKarl Rupp 
3472a6744ebSBarry Smith   pc->ops->apply           = PCApply_Galerkin;
3482a6744ebSBarry Smith   pc->ops->setup           = PCSetUp_Galerkin;
349a06653b4SBarry Smith   pc->ops->reset           = PCReset_Galerkin;
3502a6744ebSBarry Smith   pc->ops->destroy         = PCDestroy_Galerkin;
3512a6744ebSBarry Smith   pc->ops->view            = PCView_Galerkin;
3524ac220ccSBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Galerkin;
3534ac220ccSBarry Smith   pc->ops->applyrichardson = NULL;
3542a6744ebSBarry Smith 
355ce94432eSBarry Smith   ierr = KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp);CHKERRQ(ierr);
356422a814eSBarry Smith   ierr = KSPSetErrorIfNotConverged(jac->ksp,pc->erroriffailure);CHKERRQ(ierr);
3571cee3971SBarry Smith   ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);CHKERRQ(ierr);
3582a6744ebSBarry Smith 
3592a6744ebSBarry Smith   pc->data = (void*)jac;
3602a6744ebSBarry Smith 
361bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin);CHKERRQ(ierr);
362bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin);CHKERRQ(ierr);
363bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin);CHKERRQ(ierr);
364*b3402f20SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetComputeSubmatrix_C",PCGalerkinSetComputeSubmatrix_Galerkin);CHKERRQ(ierr);
3652a6744ebSBarry Smith   PetscFunctionReturn(0);
3662a6744ebSBarry Smith }
3672a6744ebSBarry Smith 
368