xref: /petsc/src/ksp/pc/impls/galerkin/galerkin.c (revision 910cf402deff9031709e244fa7c1e84ef2fdc3da)
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);
28c0decd05SBarry 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 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
1732a6744ebSBarry Smith            PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
1742a6744ebSBarry Smith 
1752a6744ebSBarry Smith @*/
1767087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetRestriction(PC pc,Mat R)
1772a6744ebSBarry Smith {
1784ac538c5SBarry Smith   PetscErrorCode ierr;
1792a6744ebSBarry Smith 
1802a6744ebSBarry Smith   PetscFunctionBegin;
1810700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1824ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetRestriction_C",(PC,Mat),(pc,R));CHKERRQ(ierr);
1832a6744ebSBarry Smith   PetscFunctionReturn(0);
1842a6744ebSBarry Smith }
1852a6744ebSBarry Smith 
1862a6744ebSBarry Smith /*@
1872a6744ebSBarry Smith    PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner
1882a6744ebSBarry Smith 
189ad4df100SBarry Smith    Logically Collective on PC
1902a6744ebSBarry Smith 
1912a6744ebSBarry Smith    Input Parameter:
1922a6744ebSBarry Smith +  pc - the preconditioner context
1932a6744ebSBarry Smith -  R - the interpolation operator
1942a6744ebSBarry Smith 
19595452b02SPatrick Sanan    Notes:
19695452b02SPatrick Sanan     Either this or PCGalerkinSetRestriction() or both must be called
1972a6744ebSBarry Smith 
1982a6744ebSBarry Smith    Level: Intermediate
1992a6744ebSBarry Smith 
2002a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
2012a6744ebSBarry Smith            PCGalerkinSetRestriction(), PCGalerkinGetKSP()
2022a6744ebSBarry Smith 
2032a6744ebSBarry Smith @*/
2047087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetInterpolation(PC pc,Mat P)
2052a6744ebSBarry Smith {
2064ac538c5SBarry Smith   PetscErrorCode ierr;
2072a6744ebSBarry Smith 
2082a6744ebSBarry Smith   PetscFunctionBegin;
2090700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2104ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));CHKERRQ(ierr);
2112a6744ebSBarry Smith   PetscFunctionReturn(0);
2122a6744ebSBarry Smith }
2132a6744ebSBarry Smith 
2142a6744ebSBarry Smith /*@
215b3402f20SBarry Smith    PCGalerkinSetComputeSubmatrix - Provide a routine that will be called to compute the Galerkin submatrix
216b3402f20SBarry Smith 
217b3402f20SBarry Smith    Logically Collective
218b3402f20SBarry Smith 
219b3402f20SBarry Smith    Input Parameter:
220b3402f20SBarry Smith +  pc - the preconditioner context
221b3402f20SBarry Smith .  computeAsub - routine that computes the submatrix from the global matrix
222b3402f20SBarry Smith -  ctx - context used by the routine, or NULL
223b3402f20SBarry Smith 
224b3402f20SBarry Smith    Calling sequence of computeAsub:
225b3402f20SBarry Smith $    computeAsub(PC pc,Mat A, Mat Ap, Mat *cAP,void *ctx);
226b3402f20SBarry Smith 
227b3402f20SBarry Smith +  PC - the Galerkin PC
228b3402f20SBarry Smith .  A - the matrix in the Galerkin PC
229b3402f20SBarry Smith .  Ap - the computed submatrix from any previous computation, if NULL it has not previously been computed
230b3402f20SBarry Smith .  cAp - the submatrix computed by this routine
231b3402f20SBarry Smith -  ctx - optional user-defined function context
232b3402f20SBarry Smith 
233b3402f20SBarry Smith    Level: Intermediate
234b3402f20SBarry Smith 
23595452b02SPatrick Sanan    Notes:
23695452b02SPatrick Sanan     Instead of providing this routine you can call PCGalerkinGetKSP() and then KSPSetOperators() to provide the submatrix,
237b3402f20SBarry Smith           but that will not work for multiple KSPSolves with different matrices unless you call it for each solve.
238b3402f20SBarry Smith 
239*910cf402Sprj-           This routine is called each time the outer matrix is changed. In the first call the Ap argument is NULL and the routine should create the
240b3402f20SBarry Smith           matrix and computes its values in cAp. On each subsequent call the routine should up the Ap matrix.
241b3402f20SBarry Smith 
24295452b02SPatrick Sanan    Developer Notes:
24395452b02SPatrick Sanan     If the user does not call this routine nor call PCGalerkinGetKSP() and KSPSetOperators() then PCGalerkin could
244b3402f20SBarry Smith                     could automatically compute the submatrix via calls to MatGalerkin() or MatRARt()
245b3402f20SBarry Smith 
246b3402f20SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
247b3402f20SBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
248b3402f20SBarry Smith 
249b3402f20SBarry Smith @*/
250b3402f20SBarry Smith PetscErrorCode  PCGalerkinSetComputeSubmatrix(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx)
251b3402f20SBarry Smith {
252b3402f20SBarry Smith   PetscErrorCode ierr;
253b3402f20SBarry Smith 
254b3402f20SBarry Smith   PetscFunctionBegin;
255b3402f20SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
256b3402f20SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetComputeSubmatrix_C",(PC,PetscErrorCode (*)(PC,Mat,Mat,Mat*,void*),void*),(pc,computeAsub,ctx));CHKERRQ(ierr);
257b3402f20SBarry Smith   PetscFunctionReturn(0);
258b3402f20SBarry Smith }
259b3402f20SBarry Smith 
260b3402f20SBarry Smith /*@
2612a6744ebSBarry Smith    PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC.
2622a6744ebSBarry Smith 
2632a6744ebSBarry Smith    Not Collective
2642a6744ebSBarry Smith 
2652a6744ebSBarry Smith    Input Parameter:
2662a6744ebSBarry Smith .  pc - the preconditioner context
2672a6744ebSBarry Smith 
2682a6744ebSBarry Smith    Output Parameters:
2692a6744ebSBarry Smith .  ksp - the KSP object
2702a6744ebSBarry Smith 
2712a6744ebSBarry Smith    Level: Intermediate
2722a6744ebSBarry Smith 
27395452b02SPatrick Sanan    Notes:
27495452b02SPatrick Sanan     Once you have called this routine you can call KSPSetOperators() on the resulting ksp to provide the operator for the Galerkin problem,
275b3402f20SBarry Smith           an alternative is to use PCGalerkinSetComputeSubmatrix() to provide a routine that computes the submatrix as needed.
276b3402f20SBarry Smith 
2772a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
278b3402f20SBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinSetComputeSubmatrix()
2792a6744ebSBarry Smith 
2802a6744ebSBarry Smith @*/
2817087cfbeSBarry Smith PetscErrorCode  PCGalerkinGetKSP(PC pc,KSP *ksp)
2822a6744ebSBarry Smith {
2834ac538c5SBarry Smith   PetscErrorCode ierr;
2842a6744ebSBarry Smith 
2852a6744ebSBarry Smith   PetscFunctionBegin;
2860700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2872a6744ebSBarry Smith   PetscValidPointer(ksp,2);
2884ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr);
2892a6744ebSBarry Smith   PetscFunctionReturn(0);
2902a6744ebSBarry Smith }
2912a6744ebSBarry Smith 
2924ac220ccSBarry Smith static PetscErrorCode PCSetFromOptions_Galerkin(PetscOptionItems *PetscOptionsObject,PC pc)
2934ac220ccSBarry Smith {
2944ac220ccSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
2954ac220ccSBarry Smith   PetscErrorCode ierr;
2964ac220ccSBarry Smith   const char     *prefix;
2974ac220ccSBarry Smith   PetscBool      flg;
2984ac220ccSBarry Smith 
2994ac220ccSBarry Smith   PetscFunctionBegin;
3004ac220ccSBarry Smith   ierr = KSPGetOptionsPrefix(jac->ksp,&prefix);CHKERRQ(ierr);
3014ac220ccSBarry Smith   ierr = PetscStrendswith(prefix,"galerkin_",&flg);CHKERRQ(ierr);
3024ac220ccSBarry Smith   if (!flg) {
3034ac220ccSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
3044ac220ccSBarry Smith     ierr = KSPSetOptionsPrefix(jac->ksp,prefix);CHKERRQ(ierr);
3054ac220ccSBarry Smith     ierr = KSPAppendOptionsPrefix(jac->ksp,"galerkin_");CHKERRQ(ierr);
3064ac220ccSBarry Smith   }
3074ac220ccSBarry Smith 
3084ac220ccSBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Galerkin options");CHKERRQ(ierr);
3094ac220ccSBarry Smith   if (jac->ksp) {
3104ac220ccSBarry Smith     ierr = KSPSetFromOptions(jac->ksp);CHKERRQ(ierr);
3114ac220ccSBarry Smith   }
3124ac220ccSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
3134ac220ccSBarry Smith   PetscFunctionReturn(0);
3144ac220ccSBarry Smith }
3152a6744ebSBarry Smith 
3162a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/
3172a6744ebSBarry Smith 
3182a6744ebSBarry Smith /*MC
3192a6744ebSBarry Smith      PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T)
3202a6744ebSBarry Smith 
3212a6744ebSBarry Smith $   Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by
3227817a140SBarry Smith $   PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....)
3232a6744ebSBarry Smith 
3242a6744ebSBarry Smith    Level: intermediate
3252a6744ebSBarry Smith 
326b59c8b46SBarry Smith    Developer Note: If KSPSetOperators() has not been called on the inner KSP then PCGALERKIN could use MatRARt() or MatPtAP() to compute
3277817a140SBarry Smith                    the operators automatically.
3287817a140SBarry Smith                    Should there be a prefix for the inner KSP.
3297817a140SBarry Smith                    There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP
3307817a140SBarry Smith 
3312a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
3322a6744ebSBarry Smith            PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
3332a6744ebSBarry Smith 
3342a6744ebSBarry Smith M*/
3352a6744ebSBarry Smith 
3368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc)
3372a6744ebSBarry Smith {
3382a6744ebSBarry Smith   PetscErrorCode ierr;
3392a6744ebSBarry Smith   PC_Galerkin    *jac;
3402a6744ebSBarry Smith 
3412a6744ebSBarry Smith   PetscFunctionBegin;
342b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
3432fa5cd67SKarl Rupp 
3442a6744ebSBarry Smith   pc->ops->apply           = PCApply_Galerkin;
3452a6744ebSBarry Smith   pc->ops->setup           = PCSetUp_Galerkin;
346a06653b4SBarry Smith   pc->ops->reset           = PCReset_Galerkin;
3472a6744ebSBarry Smith   pc->ops->destroy         = PCDestroy_Galerkin;
3482a6744ebSBarry Smith   pc->ops->view            = PCView_Galerkin;
3494ac220ccSBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Galerkin;
3504ac220ccSBarry Smith   pc->ops->applyrichardson = NULL;
3512a6744ebSBarry Smith 
352ce94432eSBarry Smith   ierr = KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp);CHKERRQ(ierr);
353422a814eSBarry Smith   ierr = KSPSetErrorIfNotConverged(jac->ksp,pc->erroriffailure);CHKERRQ(ierr);
3541cee3971SBarry Smith   ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);CHKERRQ(ierr);
3552a6744ebSBarry Smith 
3562a6744ebSBarry Smith   pc->data = (void*)jac;
3572a6744ebSBarry Smith 
358bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin);CHKERRQ(ierr);
359bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin);CHKERRQ(ierr);
360bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin);CHKERRQ(ierr);
361b3402f20SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetComputeSubmatrix_C",PCGalerkinSetComputeSubmatrix_Galerkin);CHKERRQ(ierr);
3622a6744ebSBarry Smith   PetscFunctionReturn(0);
3632a6744ebSBarry Smith }
3642a6744ebSBarry Smith 
365