xref: /petsc/src/ksp/pc/impls/galerkin/galerkin.c (revision 95452b02e12c0ee11232c7ff2b24b568a8e07e43)
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;
12b3402f20SBarry Smith   PetscErrorCode (*computeasub)(PC,Mat,Mat,Mat*,void*);
13b3402f20SBarry 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;
44b3402f20SBarry Smith   if (jac->computeasub) {
45b3402f20SBarry Smith     Mat Ap;
46b3402f20SBarry Smith     if (!pc->setupcalled) {
47b3402f20SBarry Smith       ierr = (*jac->computeasub)(pc,pc->pmat,NULL,&Ap,jac->computeasub_ctx);CHKERRQ(ierr);
48b3402f20SBarry Smith       ierr = KSPSetOperators(jac->ksp,Ap,Ap);CHKERRQ(ierr);
49b3402f20SBarry Smith       ierr = MatDestroy(&Ap);CHKERRQ(ierr);
50b3402f20SBarry Smith     } else {
51b3402f20SBarry Smith       ierr = KSPGetOperators(jac->ksp,NULL,&Ap);CHKERRQ(ierr);
52b3402f20SBarry Smith       ierr = (*jac->computeasub)(pc,pc->pmat,Ap,NULL,jac->computeasub_ctx);CHKERRQ(ierr);
53b3402f20SBarry Smith     }
54b3402f20SBarry Smith   }
55b3402f20SBarry 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 */
67b3402f20SBarry 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,"  KSP on Galerkin follow\n");CHKERRQ(ierr);
1072a6744ebSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  ---------------------------------\n");CHKERRQ(ierr);
1082a6744ebSBarry Smith   }
1092a6744ebSBarry Smith   ierr = KSPView(jac->ksp,viewer);CHKERRQ(ierr);
1102a6744ebSBarry Smith   PetscFunctionReturn(0);
1112a6744ebSBarry Smith }
1122a6744ebSBarry Smith 
1131e6b0712SBarry Smith static PetscErrorCode  PCGalerkinGetKSP_Galerkin(PC pc,KSP *ksp)
1142a6744ebSBarry Smith {
1152a6744ebSBarry Smith   PC_Galerkin *jac = (PC_Galerkin*)pc->data;
1162a6744ebSBarry Smith 
1172a6744ebSBarry Smith   PetscFunctionBegin;
1182a6744ebSBarry Smith   *ksp = jac->ksp;
1192a6744ebSBarry Smith   PetscFunctionReturn(0);
1202a6744ebSBarry Smith }
1212a6744ebSBarry Smith 
1221e6b0712SBarry Smith static PetscErrorCode  PCGalerkinSetRestriction_Galerkin(PC pc,Mat R)
1232a6744ebSBarry Smith {
1242a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1252a6744ebSBarry Smith   PetscErrorCode ierr;
1262a6744ebSBarry Smith 
1272a6744ebSBarry Smith   PetscFunctionBegin;
128c3122656SLisandro Dalcin   ierr   = PetscObjectReference((PetscObject)R);CHKERRQ(ierr);
1296bf464f9SBarry Smith   ierr   = MatDestroy(&jac->R);CHKERRQ(ierr);
1302a6744ebSBarry Smith   jac->R = R;
1312a6744ebSBarry Smith   PetscFunctionReturn(0);
1322a6744ebSBarry Smith }
1332a6744ebSBarry Smith 
1341e6b0712SBarry Smith static PetscErrorCode  PCGalerkinSetInterpolation_Galerkin(PC pc,Mat P)
1352a6744ebSBarry Smith {
1362a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1372a6744ebSBarry Smith   PetscErrorCode ierr;
1382a6744ebSBarry Smith 
1392a6744ebSBarry Smith   PetscFunctionBegin;
140c3122656SLisandro Dalcin   ierr   = PetscObjectReference((PetscObject)P);CHKERRQ(ierr);
1416bf464f9SBarry Smith   ierr   = MatDestroy(&jac->P);CHKERRQ(ierr);
1422a6744ebSBarry Smith   jac->P = P;
1432a6744ebSBarry Smith   PetscFunctionReturn(0);
1442a6744ebSBarry Smith }
1452a6744ebSBarry Smith 
146b3402f20SBarry Smith static PetscErrorCode  PCGalerkinSetComputeSubmatrix_Galerkin(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx)
147b3402f20SBarry Smith {
148b3402f20SBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
149b3402f20SBarry Smith 
150b3402f20SBarry Smith   PetscFunctionBegin;
151b3402f20SBarry Smith   jac->computeasub     = computeAsub;
152b3402f20SBarry Smith   jac->computeasub_ctx = ctx;
153b3402f20SBarry Smith   PetscFunctionReturn(0);
154b3402f20SBarry Smith }
155b3402f20SBarry Smith 
1562a6744ebSBarry Smith /* -------------------------------------------------------------------------------- */
1572a6744ebSBarry Smith /*@
1582a6744ebSBarry Smith    PCGalerkinSetRestriction - Sets the restriction operator for the "Galerkin-type" preconditioner
1592a6744ebSBarry Smith 
160ad4df100SBarry Smith    Logically Collective on PC
1612a6744ebSBarry Smith 
1622a6744ebSBarry Smith    Input Parameter:
1632a6744ebSBarry Smith +  pc - the preconditioner context
1642a6744ebSBarry Smith -  R - the restriction operator
1652a6744ebSBarry Smith 
166*95452b02SPatrick Sanan    Notes:
167*95452b02SPatrick Sanan     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 
196*95452b02SPatrick Sanan    Notes:
197*95452b02SPatrick Sanan     Either this or PCGalerkinSetRestriction() or both must be called
1982a6744ebSBarry Smith 
1992a6744ebSBarry Smith    Level: Intermediate
2002a6744ebSBarry Smith 
2012a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
2022a6744ebSBarry Smith 
2032a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
2042a6744ebSBarry Smith            PCGalerkinSetRestriction(), PCGalerkinGetKSP()
2052a6744ebSBarry Smith 
2062a6744ebSBarry Smith @*/
2077087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetInterpolation(PC pc,Mat P)
2082a6744ebSBarry Smith {
2094ac538c5SBarry Smith   PetscErrorCode ierr;
2102a6744ebSBarry Smith 
2112a6744ebSBarry Smith   PetscFunctionBegin;
2120700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2134ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));CHKERRQ(ierr);
2142a6744ebSBarry Smith   PetscFunctionReturn(0);
2152a6744ebSBarry Smith }
2162a6744ebSBarry Smith 
2172a6744ebSBarry Smith /*@
218b3402f20SBarry Smith    PCGalerkinSetComputeSubmatrix - Provide a routine that will be called to compute the Galerkin submatrix
219b3402f20SBarry Smith 
220b3402f20SBarry Smith    Logically Collective
221b3402f20SBarry Smith 
222b3402f20SBarry Smith    Input Parameter:
223b3402f20SBarry Smith +  pc - the preconditioner context
224b3402f20SBarry Smith .  computeAsub - routine that computes the submatrix from the global matrix
225b3402f20SBarry Smith -  ctx - context used by the routine, or NULL
226b3402f20SBarry Smith 
227b3402f20SBarry Smith    Calling sequence of computeAsub:
228b3402f20SBarry Smith $    computeAsub(PC pc,Mat A, Mat Ap, Mat *cAP,void *ctx);
229b3402f20SBarry Smith 
230b3402f20SBarry Smith +  PC - the Galerkin PC
231b3402f20SBarry Smith .  A - the matrix in the Galerkin PC
232b3402f20SBarry Smith .  Ap - the computed submatrix from any previous computation, if NULL it has not previously been computed
233b3402f20SBarry Smith .  cAp - the submatrix computed by this routine
234b3402f20SBarry Smith -  ctx - optional user-defined function context
235b3402f20SBarry Smith 
236b3402f20SBarry Smith    Level: Intermediate
237b3402f20SBarry Smith 
238*95452b02SPatrick Sanan    Notes:
239*95452b02SPatrick Sanan     Instead of providing this routine you can call PCGalerkinGetKSP() and then KSPSetOperators() to provide the submatrix,
240b3402f20SBarry Smith           but that will not work for multiple KSPSolves with different matrices unless you call it for each solve.
241b3402f20SBarry Smith 
242b3402f20SBarry 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
243b3402f20SBarry Smith           matrix and computes its values in cAp. On each subsequent call the routine should up the Ap matrix.
244b3402f20SBarry Smith 
245*95452b02SPatrick Sanan    Developer Notes:
246*95452b02SPatrick Sanan     If the user does not call this routine nor call PCGalerkinGetKSP() and KSPSetOperators() then PCGalerkin could
247b3402f20SBarry Smith                     could automatically compute the submatrix via calls to MatGalerkin() or MatRARt()
248b3402f20SBarry Smith 
249b3402f20SBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner
250b3402f20SBarry Smith 
251b3402f20SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
252b3402f20SBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
253b3402f20SBarry Smith 
254b3402f20SBarry Smith @*/
255b3402f20SBarry Smith PetscErrorCode  PCGalerkinSetComputeSubmatrix(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx)
256b3402f20SBarry Smith {
257b3402f20SBarry Smith   PetscErrorCode ierr;
258b3402f20SBarry Smith 
259b3402f20SBarry Smith   PetscFunctionBegin;
260b3402f20SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
261b3402f20SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetComputeSubmatrix_C",(PC,PetscErrorCode (*)(PC,Mat,Mat,Mat*,void*),void*),(pc,computeAsub,ctx));CHKERRQ(ierr);
262b3402f20SBarry Smith   PetscFunctionReturn(0);
263b3402f20SBarry Smith }
264b3402f20SBarry Smith 
265b3402f20SBarry Smith /*@
2662a6744ebSBarry Smith    PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC.
2672a6744ebSBarry Smith 
2682a6744ebSBarry Smith    Not Collective
2692a6744ebSBarry Smith 
2702a6744ebSBarry Smith    Input Parameter:
2712a6744ebSBarry Smith .  pc - the preconditioner context
2722a6744ebSBarry Smith 
2732a6744ebSBarry Smith    Output Parameters:
2742a6744ebSBarry Smith .  ksp - the KSP object
2752a6744ebSBarry Smith 
2762a6744ebSBarry Smith    Level: Intermediate
2772a6744ebSBarry Smith 
278*95452b02SPatrick Sanan    Notes:
279*95452b02SPatrick Sanan     Once you have called this routine you can call KSPSetOperators() on the resulting ksp to provide the operator for the Galerkin problem,
280b3402f20SBarry Smith           an alternative is to use PCGalerkinSetComputeSubmatrix() to provide a routine that computes the submatrix as needed.
281b3402f20SBarry Smith 
2822a6744ebSBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner
2832a6744ebSBarry Smith 
2842a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
285b3402f20SBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinSetComputeSubmatrix()
2862a6744ebSBarry Smith 
2872a6744ebSBarry Smith @*/
2887087cfbeSBarry Smith PetscErrorCode  PCGalerkinGetKSP(PC pc,KSP *ksp)
2892a6744ebSBarry Smith {
2904ac538c5SBarry Smith   PetscErrorCode ierr;
2912a6744ebSBarry Smith 
2922a6744ebSBarry Smith   PetscFunctionBegin;
2930700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2942a6744ebSBarry Smith   PetscValidPointer(ksp,2);
2954ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr);
2962a6744ebSBarry Smith   PetscFunctionReturn(0);
2972a6744ebSBarry Smith }
2982a6744ebSBarry Smith 
2994ac220ccSBarry Smith static PetscErrorCode PCSetFromOptions_Galerkin(PetscOptionItems *PetscOptionsObject,PC pc)
3004ac220ccSBarry Smith {
3014ac220ccSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
3024ac220ccSBarry Smith   PetscErrorCode ierr;
3034ac220ccSBarry Smith   const char     *prefix;
3044ac220ccSBarry Smith   PetscBool      flg;
3054ac220ccSBarry Smith 
3064ac220ccSBarry Smith   PetscFunctionBegin;
3074ac220ccSBarry Smith   ierr = KSPGetOptionsPrefix(jac->ksp,&prefix);CHKERRQ(ierr);
3084ac220ccSBarry Smith   ierr = PetscStrendswith(prefix,"galerkin_",&flg);CHKERRQ(ierr);
3094ac220ccSBarry Smith   if (!flg) {
3104ac220ccSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
3114ac220ccSBarry Smith     ierr = KSPSetOptionsPrefix(jac->ksp,prefix);CHKERRQ(ierr);
3124ac220ccSBarry Smith     ierr = KSPAppendOptionsPrefix(jac->ksp,"galerkin_");CHKERRQ(ierr);
3134ac220ccSBarry Smith   }
3144ac220ccSBarry Smith 
3154ac220ccSBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Galerkin options");CHKERRQ(ierr);
3164ac220ccSBarry Smith   if (jac->ksp) {
3174ac220ccSBarry Smith     ierr = KSPSetFromOptions(jac->ksp);CHKERRQ(ierr);
3184ac220ccSBarry Smith   }
3194ac220ccSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
3204ac220ccSBarry Smith   PetscFunctionReturn(0);
3214ac220ccSBarry Smith }
3222a6744ebSBarry Smith 
3232a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/
3242a6744ebSBarry Smith 
3252a6744ebSBarry Smith /*MC
3262a6744ebSBarry Smith      PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T)
3272a6744ebSBarry Smith 
3282a6744ebSBarry Smith $   Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by
3297817a140SBarry Smith $   PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....)
3302a6744ebSBarry Smith 
3312a6744ebSBarry Smith    Level: intermediate
3322a6744ebSBarry Smith 
333b59c8b46SBarry Smith    Developer Note: If KSPSetOperators() has not been called on the inner KSP then PCGALERKIN could use MatRARt() or MatPtAP() to compute
3347817a140SBarry Smith                    the operators automatically.
3357817a140SBarry Smith                    Should there be a prefix for the inner KSP.
3367817a140SBarry Smith                    There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP
3377817a140SBarry Smith 
3382a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
3392a6744ebSBarry Smith            PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
3402a6744ebSBarry Smith 
3412a6744ebSBarry Smith M*/
3422a6744ebSBarry Smith 
3438cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc)
3442a6744ebSBarry Smith {
3452a6744ebSBarry Smith   PetscErrorCode ierr;
3462a6744ebSBarry Smith   PC_Galerkin    *jac;
3472a6744ebSBarry Smith 
3482a6744ebSBarry Smith   PetscFunctionBegin;
349b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
3502fa5cd67SKarl Rupp 
3512a6744ebSBarry Smith   pc->ops->apply           = PCApply_Galerkin;
3522a6744ebSBarry Smith   pc->ops->setup           = PCSetUp_Galerkin;
353a06653b4SBarry Smith   pc->ops->reset           = PCReset_Galerkin;
3542a6744ebSBarry Smith   pc->ops->destroy         = PCDestroy_Galerkin;
3552a6744ebSBarry Smith   pc->ops->view            = PCView_Galerkin;
3564ac220ccSBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Galerkin;
3574ac220ccSBarry Smith   pc->ops->applyrichardson = NULL;
3582a6744ebSBarry Smith 
359ce94432eSBarry Smith   ierr = KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp);CHKERRQ(ierr);
360422a814eSBarry Smith   ierr = KSPSetErrorIfNotConverged(jac->ksp,pc->erroriffailure);CHKERRQ(ierr);
3611cee3971SBarry Smith   ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);CHKERRQ(ierr);
3622a6744ebSBarry Smith 
3632a6744ebSBarry Smith   pc->data = (void*)jac;
3642a6744ebSBarry Smith 
365bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin);CHKERRQ(ierr);
366bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin);CHKERRQ(ierr);
367bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin);CHKERRQ(ierr);
368b3402f20SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetComputeSubmatrix_C",PCGalerkinSetComputeSubmatrix_Galerkin);CHKERRQ(ierr);
3692a6744ebSBarry Smith   PetscFunctionReturn(0);
3702a6744ebSBarry Smith }
3712a6744ebSBarry Smith 
372