xref: /petsc/src/ksp/pc/impls/galerkin/galerkin.c (revision c0decd05c6848b80907752eef350b55c8c90e696)
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);
28*c0decd05SBarry Smith   ierr = KSPCheckSolve(jac->ksp,pc,jac->x);CHKERRQ(ierr);
292fa5cd67SKarl Rupp   if (jac->P) {
302fa5cd67SKarl Rupp     ierr = MatInterpolate(jac->P,jac->x,y);CHKERRQ(ierr);
312fa5cd67SKarl Rupp   } else {
322fa5cd67SKarl Rupp     ierr = MatInterpolate(jac->R,jac->x,y);CHKERRQ(ierr);
332fa5cd67SKarl Rupp   }
342a6744ebSBarry Smith   PetscFunctionReturn(0);
352a6744ebSBarry Smith }
362a6744ebSBarry Smith 
372a6744ebSBarry Smith static PetscErrorCode PCSetUp_Galerkin(PC pc)
382a6744ebSBarry Smith {
392a6744ebSBarry Smith   PetscErrorCode ierr;
402a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
41ace3abfcSBarry Smith   PetscBool      a;
42906ed7ccSBarry Smith   Vec            *xx,*yy;
432a6744ebSBarry Smith 
442a6744ebSBarry Smith   PetscFunctionBegin;
45b3402f20SBarry Smith   if (jac->computeasub) {
46b3402f20SBarry Smith     Mat Ap;
47b3402f20SBarry Smith     if (!pc->setupcalled) {
48b3402f20SBarry Smith       ierr = (*jac->computeasub)(pc,pc->pmat,NULL,&Ap,jac->computeasub_ctx);CHKERRQ(ierr);
49b3402f20SBarry Smith       ierr = KSPSetOperators(jac->ksp,Ap,Ap);CHKERRQ(ierr);
50b3402f20SBarry Smith       ierr = MatDestroy(&Ap);CHKERRQ(ierr);
51b3402f20SBarry Smith     } else {
52b3402f20SBarry Smith       ierr = KSPGetOperators(jac->ksp,NULL,&Ap);CHKERRQ(ierr);
53b3402f20SBarry Smith       ierr = (*jac->computeasub)(pc,pc->pmat,Ap,NULL,jac->computeasub_ctx);CHKERRQ(ierr);
54b3402f20SBarry Smith     }
55b3402f20SBarry Smith   }
56b3402f20SBarry Smith 
572a6744ebSBarry Smith   if (!jac->x) {
580298fd71SBarry Smith     ierr = KSPGetOperatorsSet(jac->ksp,&a,NULL);CHKERRQ(ierr);
59ce94432eSBarry Smith     if (!a) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set operator of PCGALERKIN KSP with PCGalerkinGetKSP()/KSPSetOperators()");
602a7a6963SBarry Smith     ierr   = KSPCreateVecs(jac->ksp,1,&xx,1,&yy);CHKERRQ(ierr);
61906ed7ccSBarry Smith     jac->x = *xx;
62906ed7ccSBarry Smith     jac->b = *yy;
63906ed7ccSBarry Smith     ierr   = PetscFree(xx);CHKERRQ(ierr);
64906ed7ccSBarry Smith     ierr   = PetscFree(yy);CHKERRQ(ierr);
652a6744ebSBarry Smith   }
664ac220ccSBarry Smith   if (!jac->R && !jac->P) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set restriction or interpolation of PCGALERKIN with PCGalerkinSetRestriction()/Interpolation()");
672a6744ebSBarry Smith   /* should check here that sizes of R/P match size of a */
68b3402f20SBarry Smith 
692a6744ebSBarry Smith   PetscFunctionReturn(0);
702a6744ebSBarry Smith }
712a6744ebSBarry Smith 
72a06653b4SBarry Smith static PetscErrorCode PCReset_Galerkin(PC pc)
732a6744ebSBarry Smith {
742a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
752a6744ebSBarry Smith   PetscErrorCode ierr;
762a6744ebSBarry Smith 
772a6744ebSBarry Smith   PetscFunctionBegin;
786bf464f9SBarry Smith   ierr = MatDestroy(&jac->R);CHKERRQ(ierr);
796bf464f9SBarry Smith   ierr = MatDestroy(&jac->P);CHKERRQ(ierr);
806bf464f9SBarry Smith   ierr = VecDestroy(&jac->x);CHKERRQ(ierr);
816bf464f9SBarry Smith   ierr = VecDestroy(&jac->b);CHKERRQ(ierr);
82a06653b4SBarry Smith   ierr = KSPReset(jac->ksp);CHKERRQ(ierr);
83a06653b4SBarry Smith   PetscFunctionReturn(0);
84a06653b4SBarry Smith }
85a06653b4SBarry Smith 
86a06653b4SBarry Smith static PetscErrorCode PCDestroy_Galerkin(PC pc)
87a06653b4SBarry Smith {
88a06653b4SBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
89a06653b4SBarry Smith   PetscErrorCode ierr;
90a06653b4SBarry Smith 
91a06653b4SBarry Smith   PetscFunctionBegin;
92fcfd50ebSBarry Smith   ierr = PCReset_Galerkin(pc);CHKERRQ(ierr);
936bf464f9SBarry Smith   ierr = KSPDestroy(&jac->ksp);CHKERRQ(ierr);
94c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
952a6744ebSBarry Smith   PetscFunctionReturn(0);
962a6744ebSBarry Smith }
972a6744ebSBarry Smith 
982a6744ebSBarry Smith static PetscErrorCode PCView_Galerkin(PC pc,PetscViewer viewer)
992a6744ebSBarry Smith {
1002a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1012a6744ebSBarry Smith   PetscErrorCode ierr;
102ace3abfcSBarry Smith   PetscBool      iascii;
1032a6744ebSBarry Smith 
1042a6744ebSBarry Smith   PetscFunctionBegin;
105251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1062a6744ebSBarry Smith   if (iascii) {
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 
147b3402f20SBarry Smith static PetscErrorCode  PCGalerkinSetComputeSubmatrix_Galerkin(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx)
148b3402f20SBarry Smith {
149b3402f20SBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
150b3402f20SBarry Smith 
151b3402f20SBarry Smith   PetscFunctionBegin;
152b3402f20SBarry Smith   jac->computeasub     = computeAsub;
153b3402f20SBarry Smith   jac->computeasub_ctx = ctx;
154b3402f20SBarry Smith   PetscFunctionReturn(0);
155b3402f20SBarry Smith }
156b3402f20SBarry 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 
16795452b02SPatrick Sanan    Notes:
16895452b02SPatrick Sanan     Either this or PCGalerkinSetInterpolation() or both must be called
1692a6744ebSBarry Smith 
1702a6744ebSBarry Smith    Level: Intermediate
1712a6744ebSBarry Smith 
1722a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
1732a6744ebSBarry Smith 
1742a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
1752a6744ebSBarry Smith            PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
1762a6744ebSBarry Smith 
1772a6744ebSBarry Smith @*/
1787087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetRestriction(PC pc,Mat R)
1792a6744ebSBarry Smith {
1804ac538c5SBarry Smith   PetscErrorCode ierr;
1812a6744ebSBarry Smith 
1822a6744ebSBarry Smith   PetscFunctionBegin;
1830700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1844ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetRestriction_C",(PC,Mat),(pc,R));CHKERRQ(ierr);
1852a6744ebSBarry Smith   PetscFunctionReturn(0);
1862a6744ebSBarry Smith }
1872a6744ebSBarry Smith 
1882a6744ebSBarry Smith /*@
1892a6744ebSBarry Smith    PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner
1902a6744ebSBarry Smith 
191ad4df100SBarry Smith    Logically Collective on PC
1922a6744ebSBarry Smith 
1932a6744ebSBarry Smith    Input Parameter:
1942a6744ebSBarry Smith +  pc - the preconditioner context
1952a6744ebSBarry Smith -  R - the interpolation operator
1962a6744ebSBarry Smith 
19795452b02SPatrick Sanan    Notes:
19895452b02SPatrick Sanan     Either this or PCGalerkinSetRestriction() or both must be called
1992a6744ebSBarry Smith 
2002a6744ebSBarry Smith    Level: Intermediate
2012a6744ebSBarry Smith 
2022a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
2032a6744ebSBarry Smith 
2042a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
2052a6744ebSBarry Smith            PCGalerkinSetRestriction(), PCGalerkinGetKSP()
2062a6744ebSBarry Smith 
2072a6744ebSBarry Smith @*/
2087087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetInterpolation(PC pc,Mat P)
2092a6744ebSBarry Smith {
2104ac538c5SBarry Smith   PetscErrorCode ierr;
2112a6744ebSBarry Smith 
2122a6744ebSBarry Smith   PetscFunctionBegin;
2130700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2144ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));CHKERRQ(ierr);
2152a6744ebSBarry Smith   PetscFunctionReturn(0);
2162a6744ebSBarry Smith }
2172a6744ebSBarry Smith 
2182a6744ebSBarry Smith /*@
219b3402f20SBarry Smith    PCGalerkinSetComputeSubmatrix - Provide a routine that will be called to compute the Galerkin submatrix
220b3402f20SBarry Smith 
221b3402f20SBarry Smith    Logically Collective
222b3402f20SBarry Smith 
223b3402f20SBarry Smith    Input Parameter:
224b3402f20SBarry Smith +  pc - the preconditioner context
225b3402f20SBarry Smith .  computeAsub - routine that computes the submatrix from the global matrix
226b3402f20SBarry Smith -  ctx - context used by the routine, or NULL
227b3402f20SBarry Smith 
228b3402f20SBarry Smith    Calling sequence of computeAsub:
229b3402f20SBarry Smith $    computeAsub(PC pc,Mat A, Mat Ap, Mat *cAP,void *ctx);
230b3402f20SBarry Smith 
231b3402f20SBarry Smith +  PC - the Galerkin PC
232b3402f20SBarry Smith .  A - the matrix in the Galerkin PC
233b3402f20SBarry Smith .  Ap - the computed submatrix from any previous computation, if NULL it has not previously been computed
234b3402f20SBarry Smith .  cAp - the submatrix computed by this routine
235b3402f20SBarry Smith -  ctx - optional user-defined function context
236b3402f20SBarry Smith 
237b3402f20SBarry Smith    Level: Intermediate
238b3402f20SBarry Smith 
23995452b02SPatrick Sanan    Notes:
24095452b02SPatrick Sanan     Instead of providing this routine you can call PCGalerkinGetKSP() and then KSPSetOperators() to provide the submatrix,
241b3402f20SBarry Smith           but that will not work for multiple KSPSolves with different matrices unless you call it for each solve.
242b3402f20SBarry Smith 
243b3402f20SBarry 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
244b3402f20SBarry Smith           matrix and computes its values in cAp. On each subsequent call the routine should up the Ap matrix.
245b3402f20SBarry Smith 
24695452b02SPatrick Sanan    Developer Notes:
24795452b02SPatrick Sanan     If the user does not call this routine nor call PCGalerkinGetKSP() and KSPSetOperators() then PCGalerkin could
248b3402f20SBarry Smith                     could automatically compute the submatrix via calls to MatGalerkin() or MatRARt()
249b3402f20SBarry Smith 
250b3402f20SBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner
251b3402f20SBarry Smith 
252b3402f20SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
253b3402f20SBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
254b3402f20SBarry Smith 
255b3402f20SBarry Smith @*/
256b3402f20SBarry Smith PetscErrorCode  PCGalerkinSetComputeSubmatrix(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx)
257b3402f20SBarry Smith {
258b3402f20SBarry Smith   PetscErrorCode ierr;
259b3402f20SBarry Smith 
260b3402f20SBarry Smith   PetscFunctionBegin;
261b3402f20SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
262b3402f20SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetComputeSubmatrix_C",(PC,PetscErrorCode (*)(PC,Mat,Mat,Mat*,void*),void*),(pc,computeAsub,ctx));CHKERRQ(ierr);
263b3402f20SBarry Smith   PetscFunctionReturn(0);
264b3402f20SBarry Smith }
265b3402f20SBarry Smith 
266b3402f20SBarry Smith /*@
2672a6744ebSBarry Smith    PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC.
2682a6744ebSBarry Smith 
2692a6744ebSBarry Smith    Not Collective
2702a6744ebSBarry Smith 
2712a6744ebSBarry Smith    Input Parameter:
2722a6744ebSBarry Smith .  pc - the preconditioner context
2732a6744ebSBarry Smith 
2742a6744ebSBarry Smith    Output Parameters:
2752a6744ebSBarry Smith .  ksp - the KSP object
2762a6744ebSBarry Smith 
2772a6744ebSBarry Smith    Level: Intermediate
2782a6744ebSBarry Smith 
27995452b02SPatrick Sanan    Notes:
28095452b02SPatrick Sanan     Once you have called this routine you can call KSPSetOperators() on the resulting ksp to provide the operator for the Galerkin problem,
281b3402f20SBarry Smith           an alternative is to use PCGalerkinSetComputeSubmatrix() to provide a routine that computes the submatrix as needed.
282b3402f20SBarry Smith 
2832a6744ebSBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner
2842a6744ebSBarry Smith 
2852a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
286b3402f20SBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinSetComputeSubmatrix()
2872a6744ebSBarry Smith 
2882a6744ebSBarry Smith @*/
2897087cfbeSBarry Smith PetscErrorCode  PCGalerkinGetKSP(PC pc,KSP *ksp)
2902a6744ebSBarry Smith {
2914ac538c5SBarry Smith   PetscErrorCode ierr;
2922a6744ebSBarry Smith 
2932a6744ebSBarry Smith   PetscFunctionBegin;
2940700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2952a6744ebSBarry Smith   PetscValidPointer(ksp,2);
2964ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr);
2972a6744ebSBarry Smith   PetscFunctionReturn(0);
2982a6744ebSBarry Smith }
2992a6744ebSBarry Smith 
3004ac220ccSBarry Smith static PetscErrorCode PCSetFromOptions_Galerkin(PetscOptionItems *PetscOptionsObject,PC pc)
3014ac220ccSBarry Smith {
3024ac220ccSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
3034ac220ccSBarry Smith   PetscErrorCode ierr;
3044ac220ccSBarry Smith   const char     *prefix;
3054ac220ccSBarry Smith   PetscBool      flg;
3064ac220ccSBarry Smith 
3074ac220ccSBarry Smith   PetscFunctionBegin;
3084ac220ccSBarry Smith   ierr = KSPGetOptionsPrefix(jac->ksp,&prefix);CHKERRQ(ierr);
3094ac220ccSBarry Smith   ierr = PetscStrendswith(prefix,"galerkin_",&flg);CHKERRQ(ierr);
3104ac220ccSBarry Smith   if (!flg) {
3114ac220ccSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
3124ac220ccSBarry Smith     ierr = KSPSetOptionsPrefix(jac->ksp,prefix);CHKERRQ(ierr);
3134ac220ccSBarry Smith     ierr = KSPAppendOptionsPrefix(jac->ksp,"galerkin_");CHKERRQ(ierr);
3144ac220ccSBarry Smith   }
3154ac220ccSBarry Smith 
3164ac220ccSBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Galerkin options");CHKERRQ(ierr);
3174ac220ccSBarry Smith   if (jac->ksp) {
3184ac220ccSBarry Smith     ierr = KSPSetFromOptions(jac->ksp);CHKERRQ(ierr);
3194ac220ccSBarry Smith   }
3204ac220ccSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
3214ac220ccSBarry Smith   PetscFunctionReturn(0);
3224ac220ccSBarry Smith }
3232a6744ebSBarry Smith 
3242a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/
3252a6744ebSBarry Smith 
3262a6744ebSBarry Smith /*MC
3272a6744ebSBarry Smith      PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T)
3282a6744ebSBarry Smith 
3292a6744ebSBarry Smith $   Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by
3307817a140SBarry Smith $   PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....)
3312a6744ebSBarry Smith 
3322a6744ebSBarry Smith    Level: intermediate
3332a6744ebSBarry Smith 
334b59c8b46SBarry Smith    Developer Note: If KSPSetOperators() has not been called on the inner KSP then PCGALERKIN could use MatRARt() or MatPtAP() to compute
3357817a140SBarry Smith                    the operators automatically.
3367817a140SBarry Smith                    Should there be a prefix for the inner KSP.
3377817a140SBarry Smith                    There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP
3387817a140SBarry Smith 
3392a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
3402a6744ebSBarry Smith            PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
3412a6744ebSBarry Smith 
3422a6744ebSBarry Smith M*/
3432a6744ebSBarry Smith 
3448cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc)
3452a6744ebSBarry Smith {
3462a6744ebSBarry Smith   PetscErrorCode ierr;
3472a6744ebSBarry Smith   PC_Galerkin    *jac;
3482a6744ebSBarry Smith 
3492a6744ebSBarry Smith   PetscFunctionBegin;
350b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
3512fa5cd67SKarl Rupp 
3522a6744ebSBarry Smith   pc->ops->apply           = PCApply_Galerkin;
3532a6744ebSBarry Smith   pc->ops->setup           = PCSetUp_Galerkin;
354a06653b4SBarry Smith   pc->ops->reset           = PCReset_Galerkin;
3552a6744ebSBarry Smith   pc->ops->destroy         = PCDestroy_Galerkin;
3562a6744ebSBarry Smith   pc->ops->view            = PCView_Galerkin;
3574ac220ccSBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Galerkin;
3584ac220ccSBarry Smith   pc->ops->applyrichardson = NULL;
3592a6744ebSBarry Smith 
360ce94432eSBarry Smith   ierr = KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp);CHKERRQ(ierr);
361422a814eSBarry Smith   ierr = KSPSetErrorIfNotConverged(jac->ksp,pc->erroriffailure);CHKERRQ(ierr);
3621cee3971SBarry Smith   ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);CHKERRQ(ierr);
3632a6744ebSBarry Smith 
3642a6744ebSBarry Smith   pc->data = (void*)jac;
3652a6744ebSBarry Smith 
366bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin);CHKERRQ(ierr);
367bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin);CHKERRQ(ierr);
368bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin);CHKERRQ(ierr);
369b3402f20SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetComputeSubmatrix_C",PCGalerkinSetComputeSubmatrix_Galerkin);CHKERRQ(ierr);
3702a6744ebSBarry Smith   PetscFunctionReturn(0);
3712a6744ebSBarry Smith }
3722a6744ebSBarry Smith 
373