xref: /petsc/src/ksp/pc/impls/composite/composite.c (revision 450d59eb555ff46765abad00df698152724a1b1c)
1dba47a55SKris Buschelman 
24b9ad928SBarry Smith /*
34b9ad928SBarry Smith       Defines a preconditioner that can consist of a collection of PCs
44b9ad928SBarry Smith */
5af0996ceSBarry Smith #include <petsc/private/pcimpl.h>
6c6db04a5SJed Brown #include <petscksp.h>            /*I "petscksp.h" I*/
74b9ad928SBarry Smith 
84b9ad928SBarry Smith typedef struct _PC_CompositeLink *PC_CompositeLink;
94b9ad928SBarry Smith struct _PC_CompositeLink {
104b9ad928SBarry Smith   PC               pc;
114b9ad928SBarry Smith   PC_CompositeLink next;
12421e10b8SBarry Smith   PC_CompositeLink previous;
134b9ad928SBarry Smith };
144b9ad928SBarry Smith 
154b9ad928SBarry Smith typedef struct {
164b9ad928SBarry Smith   PC_CompositeLink head;
174b9ad928SBarry Smith   PCCompositeType  type;
184b9ad928SBarry Smith   Vec              work1;
194b9ad928SBarry Smith   Vec              work2;
204b9ad928SBarry Smith   PetscScalar      alpha;
214b9ad928SBarry Smith } PC_Composite;
224b9ad928SBarry Smith 
234b9ad928SBarry Smith #undef __FUNCT__
244b9ad928SBarry Smith #define __FUNCT__ "PCApply_Composite_Multiplicative"
256849ba73SBarry Smith static PetscErrorCode PCApply_Composite_Multiplicative(PC pc,Vec x,Vec y)
264b9ad928SBarry Smith {
27dfbe8321SBarry Smith   PetscErrorCode   ierr;
284b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
294b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
304b9ad928SBarry Smith   Mat              mat  = pc->pmat;
314b9ad928SBarry Smith 
324b9ad928SBarry Smith   PetscFunctionBegin;
33*450d59ebSPatrick Farrell 
34ce94432eSBarry Smith   if (!next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPC() or -pc_composite_pcs");
35*450d59ebSPatrick Farrell 
36*450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
37*450d59ebSPatrick Farrell   while (next) {
38*450d59ebSPatrick Farrell     ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
39*450d59ebSPatrick Farrell     next = next->next;
40*450d59ebSPatrick Farrell   }
41*450d59ebSPatrick Farrell   next = jac->head;
42*450d59ebSPatrick Farrell 
434b9ad928SBarry Smith   if (next->next && !jac->work2) { /* allocate second work vector */
444b9ad928SBarry Smith     ierr = VecDuplicate(jac->work1,&jac->work2);CHKERRQ(ierr);
454b9ad928SBarry Smith   }
4649517cdeSBarry Smith   if (pc->useAmat) mat = pc->mat;
4709b21952SJed Brown   ierr = PCApply(next->pc,x,y);CHKERRQ(ierr);                      /* y <- B x */
484b9ad928SBarry Smith   while (next->next) {
494b9ad928SBarry Smith     next = next->next;
5009b21952SJed Brown     ierr = MatMult(mat,y,jac->work1);CHKERRQ(ierr);                /* work1 <- A y */
5109b21952SJed Brown     ierr = VecWAXPY(jac->work2,-1.0,jac->work1,x);CHKERRQ(ierr);   /* work2 <- x - work1 */
5251f519a2SBarry Smith     ierr = VecSet(jac->work1,0.0);CHKERRQ(ierr);  /* zero since some PC's may not set all entries in the result */
5309b21952SJed Brown     ierr = PCApply(next->pc,jac->work2,jac->work1);CHKERRQ(ierr);  /* work1 <- C work2 */
5409b21952SJed Brown     ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);                /* y <- y + work1 = B x + C (x - A B x) = (B + C (1 - A B)) x */
554b9ad928SBarry Smith   }
56421e10b8SBarry Smith   if (jac->type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
57421e10b8SBarry Smith     while (next->previous) {
58421e10b8SBarry Smith       next = next->previous;
59421e10b8SBarry Smith       ierr = MatMult(mat,y,jac->work1);CHKERRQ(ierr);
60421e10b8SBarry Smith       ierr = VecWAXPY(jac->work2,-1.0,jac->work1,x);CHKERRQ(ierr);
61421e10b8SBarry Smith       ierr = VecSet(jac->work1,0.0);CHKERRQ(ierr);  /* zero since some PC's may not set all entries in the result */
62421e10b8SBarry Smith       ierr = PCApply(next->pc,jac->work2,jac->work1);CHKERRQ(ierr);
63421e10b8SBarry Smith       ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
64421e10b8SBarry Smith     }
65421e10b8SBarry Smith   }
664b9ad928SBarry Smith   PetscFunctionReturn(0);
674b9ad928SBarry Smith }
684b9ad928SBarry Smith 
692533e041SBarry Smith #undef __FUNCT__
702533e041SBarry Smith #define __FUNCT__ "PCApplyTranspose_Composite_Multiplicative"
712533e041SBarry Smith static PetscErrorCode PCApplyTranspose_Composite_Multiplicative(PC pc,Vec x,Vec y)
722533e041SBarry Smith {
732533e041SBarry Smith   PetscErrorCode   ierr;
742533e041SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
752533e041SBarry Smith   PC_CompositeLink next = jac->head;
762533e041SBarry Smith   Mat              mat  = pc->pmat;
772533e041SBarry Smith 
782533e041SBarry Smith   PetscFunctionBegin;
79ce94432eSBarry Smith   if (!next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPC() or -pc_composite_pcs");
802533e041SBarry Smith   if (next->next && !jac->work2) { /* allocate second work vector */
812533e041SBarry Smith     ierr = VecDuplicate(jac->work1,&jac->work2);CHKERRQ(ierr);
822533e041SBarry Smith   }
8349517cdeSBarry Smith   if (pc->useAmat) mat = pc->mat;
842533e041SBarry Smith   /* locate last PC */
852533e041SBarry Smith   while (next->next) {
862533e041SBarry Smith     next = next->next;
872533e041SBarry Smith   }
882533e041SBarry Smith   ierr = PCApplyTranspose(next->pc,x,y);CHKERRQ(ierr);
892533e041SBarry Smith   while (next->previous) {
902533e041SBarry Smith     next = next->previous;
912533e041SBarry Smith     ierr = MatMultTranspose(mat,y,jac->work1);CHKERRQ(ierr);
922533e041SBarry Smith     ierr = VecWAXPY(jac->work2,-1.0,jac->work1,x);CHKERRQ(ierr);
932533e041SBarry Smith     ierr = VecSet(jac->work1,0.0);CHKERRQ(ierr);  /* zero since some PC's may not set all entries in the result */
942533e041SBarry Smith     ierr = PCApplyTranspose(next->pc,jac->work2,jac->work1);CHKERRQ(ierr);
952533e041SBarry Smith     ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
962533e041SBarry Smith   }
972533e041SBarry Smith   if (jac->type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
982533e041SBarry Smith     next = jac->head;
992533e041SBarry Smith     while (next->next) {
1002533e041SBarry Smith       next = next->next;
1012533e041SBarry Smith       ierr = MatMultTranspose(mat,y,jac->work1);CHKERRQ(ierr);
1022533e041SBarry Smith       ierr = VecWAXPY(jac->work2,-1.0,jac->work1,x);CHKERRQ(ierr);
1032533e041SBarry Smith       ierr = VecSet(jac->work1,0.0);CHKERRQ(ierr);  /* zero since some PC's may not set all entries in the result */
1042533e041SBarry Smith       ierr = PCApplyTranspose(next->pc,jac->work2,jac->work1);CHKERRQ(ierr);
1052533e041SBarry Smith       ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
1062533e041SBarry Smith     }
1072533e041SBarry Smith   }
1082533e041SBarry Smith   PetscFunctionReturn(0);
1092533e041SBarry Smith }
1102533e041SBarry Smith 
1114b9ad928SBarry Smith /*
1124b9ad928SBarry Smith     This is very special for a matrix of the form alpha I + R + S
1134b9ad928SBarry Smith where first preconditioner is built from alpha I + S and second from
1144b9ad928SBarry Smith alpha I + R
1154b9ad928SBarry Smith */
1164b9ad928SBarry Smith #undef __FUNCT__
1174b9ad928SBarry Smith #define __FUNCT__ "PCApply_Composite_Special"
1186849ba73SBarry Smith static PetscErrorCode PCApply_Composite_Special(PC pc,Vec x,Vec y)
1194b9ad928SBarry Smith {
120dfbe8321SBarry Smith   PetscErrorCode   ierr;
1214b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
1224b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1234b9ad928SBarry Smith 
1244b9ad928SBarry Smith   PetscFunctionBegin;
125ce94432eSBarry Smith   if (!next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPC() or -pc_composite_pcs");
126ce94432eSBarry Smith   if (!next->next || next->next->next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Special composite preconditioners requires exactly two PCs");
1274b9ad928SBarry Smith 
128*450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
129*450d59ebSPatrick Farrell   ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
130*450d59ebSPatrick Farrell   ierr = PCSetReusePreconditioner(next->next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
131*450d59ebSPatrick Farrell 
132d8fd42c4SBarry Smith   ierr = PCApply(next->pc,x,jac->work1);CHKERRQ(ierr);
133d8fd42c4SBarry Smith   ierr = PCApply(next->next->pc,jac->work1,y);CHKERRQ(ierr);
1344b9ad928SBarry Smith   PetscFunctionReturn(0);
1354b9ad928SBarry Smith }
1364b9ad928SBarry Smith 
1374b9ad928SBarry Smith #undef __FUNCT__
1384b9ad928SBarry Smith #define __FUNCT__ "PCApply_Composite_Additive"
1396849ba73SBarry Smith static PetscErrorCode PCApply_Composite_Additive(PC pc,Vec x,Vec y)
1404b9ad928SBarry Smith {
141dfbe8321SBarry Smith   PetscErrorCode   ierr;
1424b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
1434b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1444b9ad928SBarry Smith 
1454b9ad928SBarry Smith   PetscFunctionBegin;
146ce94432eSBarry Smith   if (!next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPC() or -pc_composite_pcs");
147*450d59ebSPatrick Farrell 
148*450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
149*450d59ebSPatrick Farrell   while (next) {
150*450d59ebSPatrick Farrell     ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
151*450d59ebSPatrick Farrell     next = next->next;
152*450d59ebSPatrick Farrell   }
153*450d59ebSPatrick Farrell   next = jac->head;
154*450d59ebSPatrick Farrell 
155d8fd42c4SBarry Smith   ierr = PCApply(next->pc,x,y);CHKERRQ(ierr);
1564b9ad928SBarry Smith   while (next->next) {
1574b9ad928SBarry Smith     next = next->next;
15851f519a2SBarry Smith     ierr = VecSet(jac->work1,0.0);CHKERRQ(ierr);  /* zero since some PC's may not set all entries in the result */
159d8fd42c4SBarry Smith     ierr = PCApply(next->pc,x,jac->work1);CHKERRQ(ierr);
160efb30889SBarry Smith     ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
1614b9ad928SBarry Smith   }
1624b9ad928SBarry Smith   PetscFunctionReturn(0);
1634b9ad928SBarry Smith }
1644b9ad928SBarry Smith 
1654b9ad928SBarry Smith #undef __FUNCT__
1662533e041SBarry Smith #define __FUNCT__ "PCApplyTranspose_Composite_Additive"
1672533e041SBarry Smith static PetscErrorCode PCApplyTranspose_Composite_Additive(PC pc,Vec x,Vec y)
1682533e041SBarry Smith {
1692533e041SBarry Smith   PetscErrorCode   ierr;
1702533e041SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
1712533e041SBarry Smith   PC_CompositeLink next = jac->head;
1722533e041SBarry Smith 
1732533e041SBarry Smith   PetscFunctionBegin;
174ce94432eSBarry Smith   if (!next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPC() or -pc_composite_pcs");
1752533e041SBarry Smith   ierr = PCApplyTranspose(next->pc,x,y);CHKERRQ(ierr);
1762533e041SBarry Smith   while (next->next) {
1772533e041SBarry Smith     next = next->next;
1782533e041SBarry Smith     ierr = VecSet(jac->work1,0.0);CHKERRQ(ierr);  /* zero since some PC's may not set all entries in the result */
1792533e041SBarry Smith     ierr = PCApplyTranspose(next->pc,x,jac->work1);CHKERRQ(ierr);
1802533e041SBarry Smith     ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
1812533e041SBarry Smith   }
1822533e041SBarry Smith   PetscFunctionReturn(0);
1832533e041SBarry Smith }
1842533e041SBarry Smith 
1852533e041SBarry Smith #undef __FUNCT__
1864b9ad928SBarry Smith #define __FUNCT__ "PCSetUp_Composite"
1876849ba73SBarry Smith static PetscErrorCode PCSetUp_Composite(PC pc)
1884b9ad928SBarry Smith {
189dfbe8321SBarry Smith   PetscErrorCode   ierr;
1904b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
1914b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1924b9ad928SBarry Smith 
1934b9ad928SBarry Smith   PetscFunctionBegin;
1944b9ad928SBarry Smith   if (!jac->work1) {
1952a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&jac->work1,0);CHKERRQ(ierr);
1964b9ad928SBarry Smith   }
1974b9ad928SBarry Smith   while (next) {
19823ee1639SBarry Smith     ierr = PCSetOperators(next->pc,pc->mat,pc->pmat);CHKERRQ(ierr);
1994b9ad928SBarry Smith     next = next->next;
2004b9ad928SBarry Smith   }
2014b9ad928SBarry Smith   PetscFunctionReturn(0);
2024b9ad928SBarry Smith }
2034b9ad928SBarry Smith 
2044b9ad928SBarry Smith #undef __FUNCT__
20569d2c0f9SBarry Smith #define __FUNCT__ "PCReset_Composite"
20669d2c0f9SBarry Smith static PetscErrorCode PCReset_Composite(PC pc)
20769d2c0f9SBarry Smith {
20869d2c0f9SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
20969d2c0f9SBarry Smith   PetscErrorCode   ierr;
2105f48b12bSBarry Smith   PC_CompositeLink next = jac->head;
21169d2c0f9SBarry Smith 
21269d2c0f9SBarry Smith   PetscFunctionBegin;
21369d2c0f9SBarry Smith   while (next) {
21469d2c0f9SBarry Smith     ierr = PCReset(next->pc);CHKERRQ(ierr);
21569d2c0f9SBarry Smith     next = next->next;
21669d2c0f9SBarry Smith   }
2176bf464f9SBarry Smith   ierr = VecDestroy(&jac->work1);CHKERRQ(ierr);
2186bf464f9SBarry Smith   ierr = VecDestroy(&jac->work2);CHKERRQ(ierr);
21969d2c0f9SBarry Smith   PetscFunctionReturn(0);
22069d2c0f9SBarry Smith }
22169d2c0f9SBarry Smith 
22269d2c0f9SBarry Smith #undef __FUNCT__
2234b9ad928SBarry Smith #define __FUNCT__ "PCDestroy_Composite"
2246849ba73SBarry Smith static PetscErrorCode PCDestroy_Composite(PC pc)
2254b9ad928SBarry Smith {
2264b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
227dfbe8321SBarry Smith   PetscErrorCode   ierr;
228724c2c99SHong Zhang   PC_CompositeLink next = jac->head,next_tmp;
2294b9ad928SBarry Smith 
2304b9ad928SBarry Smith   PetscFunctionBegin;
23169d2c0f9SBarry Smith   ierr = PCReset_Composite(pc);CHKERRQ(ierr);
2324b9ad928SBarry Smith   while (next) {
2336bf464f9SBarry Smith     ierr     = PCDestroy(&next->pc);CHKERRQ(ierr);
234724c2c99SHong Zhang     next_tmp = next;
2354b9ad928SBarry Smith     next     = next->next;
236724c2c99SHong Zhang     ierr     = PetscFree(next_tmp);CHKERRQ(ierr);
2374b9ad928SBarry Smith   }
238c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2394b9ad928SBarry Smith   PetscFunctionReturn(0);
2404b9ad928SBarry Smith }
2414b9ad928SBarry Smith 
2424b9ad928SBarry Smith #undef __FUNCT__
2434b9ad928SBarry Smith #define __FUNCT__ "PCSetFromOptions_Composite"
2448c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_Composite(PetscOptions *PetscOptionsObject,PC pc)
2454b9ad928SBarry Smith {
2464b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
247dfbe8321SBarry Smith   PetscErrorCode   ierr;
2489dcbbd2bSBarry Smith   PetscInt         nmax = 8,i;
2494b9ad928SBarry Smith   PC_CompositeLink next;
250e5999256SBarry Smith   char             *pcs[8];
251ace3abfcSBarry Smith   PetscBool        flg;
2524b9ad928SBarry Smith 
2534b9ad928SBarry Smith   PetscFunctionBegin;
254e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Composite preconditioner options");CHKERRQ(ierr);
2559dcbbd2bSBarry Smith   ierr = PetscOptionsEnum("-pc_composite_type","Type of composition","PCCompositeSetType",PCCompositeTypes,(PetscEnum)jac->type,(PetscEnum*)&jac->type,&flg);CHKERRQ(ierr);
25651f519a2SBarry Smith   if (flg) {
25751f519a2SBarry Smith     ierr = PCCompositeSetType(pc,jac->type);CHKERRQ(ierr);
25851f519a2SBarry Smith   }
2594b9ad928SBarry Smith   ierr = PetscOptionsStringArray("-pc_composite_pcs","List of composite solvers","PCCompositeAddPC",pcs,&nmax,&flg);CHKERRQ(ierr);
2604b9ad928SBarry Smith   if (flg) {
2614b9ad928SBarry Smith     for (i=0; i<nmax; i++) {
2624b9ad928SBarry Smith       ierr = PCCompositeAddPC(pc,pcs[i]);CHKERRQ(ierr);
263724c2c99SHong Zhang       ierr = PetscFree(pcs[i]);CHKERRQ(ierr);   /* deallocate string pcs[i], which is allocated in PetscOptionsStringArray() */
2644b9ad928SBarry Smith     }
2654b9ad928SBarry Smith   }
2664b9ad928SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2674b9ad928SBarry Smith 
2684b9ad928SBarry Smith   next = jac->head;
2694b9ad928SBarry Smith   while (next) {
2704b9ad928SBarry Smith     ierr = PCSetFromOptions(next->pc);CHKERRQ(ierr);
2714b9ad928SBarry Smith     next = next->next;
2724b9ad928SBarry Smith   }
2734b9ad928SBarry Smith   PetscFunctionReturn(0);
2744b9ad928SBarry Smith }
2754b9ad928SBarry Smith 
2764b9ad928SBarry Smith #undef __FUNCT__
2774b9ad928SBarry Smith #define __FUNCT__ "PCView_Composite"
2786849ba73SBarry Smith static PetscErrorCode PCView_Composite(PC pc,PetscViewer viewer)
2794b9ad928SBarry Smith {
2804b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
281dfbe8321SBarry Smith   PetscErrorCode   ierr;
2824b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
283ace3abfcSBarry Smith   PetscBool        iascii;
2844b9ad928SBarry Smith 
2854b9ad928SBarry Smith   PetscFunctionBegin;
286251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
28732077d6dSBarry Smith   if (iascii) {
2889dcbbd2bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Composite PC type - %s\n",PCCompositeTypes[jac->type]);CHKERRQ(ierr);
2894b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"PCs on composite preconditioner follow\n");CHKERRQ(ierr);
2904b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr);
2914b9ad928SBarry Smith   }
29232077d6dSBarry Smith   if (iascii) {
2934b9ad928SBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2944b9ad928SBarry Smith   }
2954b9ad928SBarry Smith   while (next) {
2964b9ad928SBarry Smith     ierr = PCView(next->pc,viewer);CHKERRQ(ierr);
2974b9ad928SBarry Smith     next = next->next;
2984b9ad928SBarry Smith   }
29932077d6dSBarry Smith   if (iascii) {
3004b9ad928SBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3014b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr);
3024b9ad928SBarry Smith   }
3034b9ad928SBarry Smith   PetscFunctionReturn(0);
3044b9ad928SBarry Smith }
3054b9ad928SBarry Smith 
3064b9ad928SBarry Smith /* ------------------------------------------------------------------------------*/
3074b9ad928SBarry Smith 
3084b9ad928SBarry Smith #undef __FUNCT__
3094b9ad928SBarry Smith #define __FUNCT__ "PCCompositeSpecialSetAlpha_Composite"
3101e6b0712SBarry Smith static PetscErrorCode  PCCompositeSpecialSetAlpha_Composite(PC pc,PetscScalar alpha)
3114b9ad928SBarry Smith {
3124b9ad928SBarry Smith   PC_Composite *jac = (PC_Composite*)pc->data;
3135fd66863SKarl Rupp 
3144b9ad928SBarry Smith   PetscFunctionBegin;
3154b9ad928SBarry Smith   jac->alpha = alpha;
3164b9ad928SBarry Smith   PetscFunctionReturn(0);
3174b9ad928SBarry Smith }
3184b9ad928SBarry Smith 
3194b9ad928SBarry Smith #undef __FUNCT__
3204b9ad928SBarry Smith #define __FUNCT__ "PCCompositeSetType_Composite"
3211e6b0712SBarry Smith static PetscErrorCode  PCCompositeSetType_Composite(PC pc,PCCompositeType type)
3224b9ad928SBarry Smith {
323fad69fbaSJed Brown   PC_Composite *jac = (PC_Composite*)pc->data;
324fad69fbaSJed Brown 
3254b9ad928SBarry Smith   PetscFunctionBegin;
3264b9ad928SBarry Smith   if (type == PC_COMPOSITE_ADDITIVE) {
3274b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Additive;
3282533e041SBarry Smith     pc->ops->applytranspose = PCApplyTranspose_Composite_Additive;
329421e10b8SBarry Smith   } else if (type ==  PC_COMPOSITE_MULTIPLICATIVE || type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
3304b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Multiplicative;
3312533e041SBarry Smith     pc->ops->applytranspose = PCApplyTranspose_Composite_Multiplicative;
3324b9ad928SBarry Smith   } else if (type ==  PC_COMPOSITE_SPECIAL) {
3334b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Special;
3340298fd71SBarry Smith     pc->ops->applytranspose = NULL;
335ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unkown composite preconditioner type");
336fad69fbaSJed Brown   jac->type = type;
3374b9ad928SBarry Smith   PetscFunctionReturn(0);
3384b9ad928SBarry Smith }
3394b9ad928SBarry Smith 
3404b9ad928SBarry Smith #undef __FUNCT__
341c60c7ad4SBarry Smith #define __FUNCT__ "PCCompositeGetType_Composite"
342c60c7ad4SBarry Smith static PetscErrorCode  PCCompositeGetType_Composite(PC pc,PCCompositeType *type)
343c60c7ad4SBarry Smith {
344c60c7ad4SBarry Smith   PC_Composite *jac = (PC_Composite*)pc->data;
345c60c7ad4SBarry Smith 
346c60c7ad4SBarry Smith   PetscFunctionBegin;
347c60c7ad4SBarry Smith   *type = jac->type;
348c60c7ad4SBarry Smith   PetscFunctionReturn(0);
349c60c7ad4SBarry Smith }
350c60c7ad4SBarry Smith 
351c60c7ad4SBarry Smith #undef __FUNCT__
3524b9ad928SBarry Smith #define __FUNCT__ "PCCompositeAddPC_Composite"
3531e6b0712SBarry Smith static PetscErrorCode  PCCompositeAddPC_Composite(PC pc,PCType type)
3544b9ad928SBarry Smith {
3554b9ad928SBarry Smith   PC_Composite     *jac;
3565a9f2f41SSatish Balay   PC_CompositeLink next,ilink;
357dfbe8321SBarry Smith   PetscErrorCode   ierr;
35879416396SBarry Smith   PetscInt         cnt = 0;
3592dcb1b2aSMatthew Knepley   const char       *prefix;
3602dcb1b2aSMatthew Knepley   char             newprefix[8];
3614b9ad928SBarry Smith 
3624b9ad928SBarry Smith   PetscFunctionBegin;
363b00a9115SJed Brown   ierr        = PetscNewLog(pc,&ilink);CHKERRQ(ierr);
3645a9f2f41SSatish Balay   ilink->next = 0;
365ce94432eSBarry Smith   ierr        = PCCreate(PetscObjectComm((PetscObject)pc),&ilink->pc);CHKERRQ(ierr);
366ace3abfcSBarry Smith   ierr        = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilink->pc);CHKERRQ(ierr);
3674b9ad928SBarry Smith 
3684b9ad928SBarry Smith   jac  = (PC_Composite*)pc->data;
3694b9ad928SBarry Smith   next = jac->head;
3704b9ad928SBarry Smith   if (!next) {
3715a9f2f41SSatish Balay     jac->head       = ilink;
3720298fd71SBarry Smith     ilink->previous = NULL;
3734b9ad928SBarry Smith   } else {
3744b9ad928SBarry Smith     cnt++;
3754b9ad928SBarry Smith     while (next->next) {
3764b9ad928SBarry Smith       next = next->next;
3774b9ad928SBarry Smith       cnt++;
3784b9ad928SBarry Smith     }
3795a9f2f41SSatish Balay     next->next      = ilink;
380421e10b8SBarry Smith     ilink->previous = next;
3814b9ad928SBarry Smith   }
3824b9ad928SBarry Smith   ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
3835a9f2f41SSatish Balay   ierr = PCSetOptionsPrefix(ilink->pc,prefix);CHKERRQ(ierr);
38413f74950SBarry Smith   sprintf(newprefix,"sub_%d_",(int)cnt);
3855a9f2f41SSatish Balay   ierr = PCAppendOptionsPrefix(ilink->pc,newprefix);CHKERRQ(ierr);
3864b9ad928SBarry Smith   /* type is set after prefix, because some methods may modify prefix, e.g. pcksp */
3875a9f2f41SSatish Balay   ierr = PCSetType(ilink->pc,type);CHKERRQ(ierr);
3884b9ad928SBarry Smith   PetscFunctionReturn(0);
3894b9ad928SBarry Smith }
3904b9ad928SBarry Smith 
3914b9ad928SBarry Smith #undef __FUNCT__
3928e6eba06SBarry Smith #define __FUNCT__ "PCCompositeGetNumberPC_Composite"
3938e6eba06SBarry Smith static PetscErrorCode  PCCompositeGetNumberPC_Composite(PC pc,PetscInt *n)
3948e6eba06SBarry Smith {
3958e6eba06SBarry Smith   PC_Composite     *jac;
3968e6eba06SBarry Smith   PC_CompositeLink next;
3978e6eba06SBarry Smith 
3988e6eba06SBarry Smith   PetscFunctionBegin;
3998e6eba06SBarry Smith   jac  = (PC_Composite*)pc->data;
4008e6eba06SBarry Smith   next = jac->head;
4018e6eba06SBarry Smith   *n = 0;
4028e6eba06SBarry Smith   while (next) {
4038e6eba06SBarry Smith     next = next->next;
4048e6eba06SBarry Smith     (*n) ++;
4058e6eba06SBarry Smith   }
4068e6eba06SBarry Smith   PetscFunctionReturn(0);
4078e6eba06SBarry Smith }
4088e6eba06SBarry Smith 
4098e6eba06SBarry Smith #undef __FUNCT__
4104b9ad928SBarry Smith #define __FUNCT__ "PCCompositeGetPC_Composite"
4111e6b0712SBarry Smith static PetscErrorCode  PCCompositeGetPC_Composite(PC pc,PetscInt n,PC *subpc)
4124b9ad928SBarry Smith {
4134b9ad928SBarry Smith   PC_Composite     *jac;
4144b9ad928SBarry Smith   PC_CompositeLink next;
41579416396SBarry Smith   PetscInt         i;
4164b9ad928SBarry Smith 
4174b9ad928SBarry Smith   PetscFunctionBegin;
4184b9ad928SBarry Smith   jac  = (PC_Composite*)pc->data;
4194b9ad928SBarry Smith   next = jac->head;
4204b9ad928SBarry Smith   for (i=0; i<n; i++) {
421ce94432eSBarry Smith     if (!next->next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Not enough PCs in composite preconditioner");
4224b9ad928SBarry Smith     next = next->next;
4234b9ad928SBarry Smith   }
4244b9ad928SBarry Smith   *subpc = next->pc;
4254b9ad928SBarry Smith   PetscFunctionReturn(0);
4264b9ad928SBarry Smith }
4274b9ad928SBarry Smith 
4284b9ad928SBarry Smith /* -------------------------------------------------------------------------------- */
4294b9ad928SBarry Smith #undef __FUNCT__
4304b9ad928SBarry Smith #define __FUNCT__ "PCCompositeSetType"
431f39d8e23SSatish Balay /*@
4324b9ad928SBarry Smith    PCCompositeSetType - Sets the type of composite preconditioner.
4334b9ad928SBarry Smith 
434ad4df100SBarry Smith    Logically Collective on PC
4354b9ad928SBarry Smith 
436c60c7ad4SBarry Smith    Input Parameters:
4372a6744ebSBarry Smith +  pc - the preconditioner context
4382a6744ebSBarry Smith -  type - PC_COMPOSITE_ADDITIVE (default), PC_COMPOSITE_MULTIPLICATIVE, PC_COMPOSITE_SPECIAL
4394b9ad928SBarry Smith 
4404b9ad928SBarry Smith    Options Database Key:
4414b9ad928SBarry Smith .  -pc_composite_type <type: one of multiplicative, additive, special> - Sets composite preconditioner type
4424b9ad928SBarry Smith 
4434b9ad928SBarry Smith    Level: Developer
4444b9ad928SBarry Smith 
4454b9ad928SBarry Smith .keywords: PC, set, type, composite preconditioner, additive, multiplicative
4464b9ad928SBarry Smith @*/
4477087cfbeSBarry Smith PetscErrorCode  PCCompositeSetType(PC pc,PCCompositeType type)
4484b9ad928SBarry Smith {
4497bb14e67SBarry Smith   PetscErrorCode ierr;
4504b9ad928SBarry Smith 
4514b9ad928SBarry Smith   PetscFunctionBegin;
4520700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
453c5eb9154SBarry Smith   PetscValidLogicalCollectiveEnum(pc,type,2);
4547bb14e67SBarry Smith   ierr = PetscTryMethod(pc,"PCCompositeSetType_C",(PC,PCCompositeType),(pc,type));CHKERRQ(ierr);
4554b9ad928SBarry Smith   PetscFunctionReturn(0);
4564b9ad928SBarry Smith }
4574b9ad928SBarry Smith 
4584b9ad928SBarry Smith #undef __FUNCT__
459c60c7ad4SBarry Smith #define __FUNCT__ "PCCompositeGetType"
460c60c7ad4SBarry Smith /*@
461721f67b5SBarry Smith    PCCompositeGetType - Gets the type of composite preconditioner.
462c60c7ad4SBarry Smith 
463c60c7ad4SBarry Smith    Logically Collective on PC
464c60c7ad4SBarry Smith 
465c60c7ad4SBarry Smith    Input Parameter:
466c60c7ad4SBarry Smith .  pc - the preconditioner context
467c60c7ad4SBarry Smith 
468c60c7ad4SBarry Smith    Output Parameter:
469c60c7ad4SBarry Smith .  type - PC_COMPOSITE_ADDITIVE (default), PC_COMPOSITE_MULTIPLICATIVE, PC_COMPOSITE_SPECIAL
470c60c7ad4SBarry Smith 
471c60c7ad4SBarry Smith    Options Database Key:
472c60c7ad4SBarry Smith .  -pc_composite_type <type: one of multiplicative, additive, special> - Sets composite preconditioner type
473c60c7ad4SBarry Smith 
474c60c7ad4SBarry Smith    Level: Developer
475c60c7ad4SBarry Smith 
476c60c7ad4SBarry Smith .keywords: PC, set, type, composite preconditioner, additive, multiplicative
477c60c7ad4SBarry Smith @*/
478c60c7ad4SBarry Smith PetscErrorCode  PCCompositeGetType(PC pc,PCCompositeType *type)
479c60c7ad4SBarry Smith {
480c60c7ad4SBarry Smith   PetscErrorCode ierr;
481c60c7ad4SBarry Smith 
482c60c7ad4SBarry Smith   PetscFunctionBegin;
483c60c7ad4SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
484c60c7ad4SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetType_C",(PC,PCCompositeType*),(pc,type));CHKERRQ(ierr);
485c60c7ad4SBarry Smith   PetscFunctionReturn(0);
486c60c7ad4SBarry Smith }
487c60c7ad4SBarry Smith 
488c60c7ad4SBarry Smith #undef __FUNCT__
4894b9ad928SBarry Smith #define __FUNCT__ "PCCompositeSpecialSetAlpha"
490f39d8e23SSatish Balay /*@
4914b9ad928SBarry Smith    PCCompositeSpecialSetAlpha - Sets alpha for the special composite preconditioner
4924b9ad928SBarry Smith      for alphaI + R + S
4934b9ad928SBarry Smith 
494ad4df100SBarry Smith    Logically Collective on PC
4954b9ad928SBarry Smith 
4964b9ad928SBarry Smith    Input Parameter:
4974b9ad928SBarry Smith +  pc - the preconditioner context
4984b9ad928SBarry Smith -  alpha - scale on identity
4994b9ad928SBarry Smith 
5004b9ad928SBarry Smith    Level: Developer
5014b9ad928SBarry Smith 
5024b9ad928SBarry Smith .keywords: PC, set, type, composite preconditioner, additive, multiplicative
5034b9ad928SBarry Smith @*/
5047087cfbeSBarry Smith PetscErrorCode  PCCompositeSpecialSetAlpha(PC pc,PetscScalar alpha)
5054b9ad928SBarry Smith {
5064ac538c5SBarry Smith   PetscErrorCode ierr;
5074b9ad928SBarry Smith 
5084b9ad928SBarry Smith   PetscFunctionBegin;
5090700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
510c5eb9154SBarry Smith   PetscValidLogicalCollectiveScalar(pc,alpha,2);
5114ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCCompositeSpecialSetAlpha_C",(PC,PetscScalar),(pc,alpha));CHKERRQ(ierr);
5124b9ad928SBarry Smith   PetscFunctionReturn(0);
5134b9ad928SBarry Smith }
5144b9ad928SBarry Smith 
5154b9ad928SBarry Smith #undef __FUNCT__
5164b9ad928SBarry Smith #define __FUNCT__ "PCCompositeAddPC"
5174b9ad928SBarry Smith /*@C
5184b9ad928SBarry Smith    PCCompositeAddPC - Adds another PC to the composite PC.
5194b9ad928SBarry Smith 
5204b9ad928SBarry Smith    Collective on PC
5214b9ad928SBarry Smith 
5224b9ad928SBarry Smith    Input Parameters:
5232a6744ebSBarry Smith +  pc - the preconditioner context
5242a6744ebSBarry Smith -  type - the type of the new preconditioner
5254b9ad928SBarry Smith 
5264b9ad928SBarry Smith    Level: Developer
5274b9ad928SBarry Smith 
5284b9ad928SBarry Smith .keywords: PC, composite preconditioner, add
5294b9ad928SBarry Smith @*/
53019fd82e9SBarry Smith PetscErrorCode  PCCompositeAddPC(PC pc,PCType type)
5314b9ad928SBarry Smith {
5324ac538c5SBarry Smith   PetscErrorCode ierr;
5334b9ad928SBarry Smith 
5344b9ad928SBarry Smith   PetscFunctionBegin;
5350700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
53619fd82e9SBarry Smith   ierr = PetscTryMethod(pc,"PCCompositeAddPC_C",(PC,PCType),(pc,type));CHKERRQ(ierr);
5374b9ad928SBarry Smith   PetscFunctionReturn(0);
5384b9ad928SBarry Smith }
5394b9ad928SBarry Smith 
5404b9ad928SBarry Smith #undef __FUNCT__
5418e6eba06SBarry Smith #define __FUNCT__ "PCCompositeGetNumberPC"
5428e6eba06SBarry Smith /*@
5438e6eba06SBarry Smith    PCCompositeGetNumberPC - Gets the number of PC objects in the composite PC.
5448e6eba06SBarry Smith 
5458e6eba06SBarry Smith    Not Collective
5468e6eba06SBarry Smith 
5478e6eba06SBarry Smith    Input Parameter:
5488e6eba06SBarry Smith .  pc - the preconditioner context
5498e6eba06SBarry Smith 
5508e6eba06SBarry Smith    Output Parameter:
5518e6eba06SBarry Smith .  num - the number of sub pcs
5528e6eba06SBarry Smith 
5538e6eba06SBarry Smith    Level: Developer
5548e6eba06SBarry Smith 
5558e6eba06SBarry Smith .keywords: PC, get, composite preconditioner, sub preconditioner
5568e6eba06SBarry Smith 
5578e6eba06SBarry Smith .seealso: PCCompositeGetPC()
5588e6eba06SBarry Smith @*/
5598e6eba06SBarry Smith PetscErrorCode  PCCompositeGetNumberPC(PC pc,PetscInt *num)
5608e6eba06SBarry Smith {
5618e6eba06SBarry Smith   PetscErrorCode ierr;
5628e6eba06SBarry Smith 
5638e6eba06SBarry Smith   PetscFunctionBegin;
5648e6eba06SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5658e6eba06SBarry Smith   PetscValidIntPointer(num,2);
5668e6eba06SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetNumberPC_C",(PC,PetscInt*),(pc,num));CHKERRQ(ierr);
5678e6eba06SBarry Smith   PetscFunctionReturn(0);
5688e6eba06SBarry Smith }
5698e6eba06SBarry Smith 
5708e6eba06SBarry Smith #undef __FUNCT__
5714b9ad928SBarry Smith #define __FUNCT__ "PCCompositeGetPC"
572f39d8e23SSatish Balay /*@
5734b9ad928SBarry Smith    PCCompositeGetPC - Gets one of the PC objects in the composite PC.
5744b9ad928SBarry Smith 
5754b9ad928SBarry Smith    Not Collective
5764b9ad928SBarry Smith 
5774b9ad928SBarry Smith    Input Parameter:
5782a6744ebSBarry Smith +  pc - the preconditioner context
5792a6744ebSBarry Smith -  n - the number of the pc requested
5804b9ad928SBarry Smith 
5814b9ad928SBarry Smith    Output Parameters:
5824b9ad928SBarry Smith .  subpc - the PC requested
5834b9ad928SBarry Smith 
5844b9ad928SBarry Smith    Level: Developer
5854b9ad928SBarry Smith 
5864b9ad928SBarry Smith .keywords: PC, get, composite preconditioner, sub preconditioner
5874b9ad928SBarry Smith 
5888e6eba06SBarry Smith .seealso: PCCompositeAddPC(), PCCompositeGetNumberPC()
5894b9ad928SBarry Smith @*/
5907087cfbeSBarry Smith PetscErrorCode  PCCompositeGetPC(PC pc,PetscInt n,PC *subpc)
5914b9ad928SBarry Smith {
5924ac538c5SBarry Smith   PetscErrorCode ierr;
5934b9ad928SBarry Smith 
5944b9ad928SBarry Smith   PetscFunctionBegin;
5950700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5964482741eSBarry Smith   PetscValidPointer(subpc,3);
5974ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetPC_C",(PC,PetscInt,PC*),(pc,n,subpc));CHKERRQ(ierr);
5984b9ad928SBarry Smith   PetscFunctionReturn(0);
5994b9ad928SBarry Smith }
6004b9ad928SBarry Smith 
6014b9ad928SBarry Smith /* -------------------------------------------------------------------------------------------*/
6024b9ad928SBarry Smith 
6034b9ad928SBarry Smith /*MC
6044b9ad928SBarry Smith      PCCOMPOSITE - Build a preconditioner by composing together several preconditioners
6054b9ad928SBarry Smith 
6064b9ad928SBarry Smith    Options Database Keys:
6072eab2d5bSJungho Lee +  -pc_composite_type <type: one of multiplicative, additive, symmetric_multiplicative, special> - Sets composite preconditioner type
60849517cdeSBarry Smith .  -pc_use_amat - Activates PCSetUseAmat()
60951f519a2SBarry Smith -  -pc_composite_pcs - <pc0,pc1,...> list of PCs to compose
6104b9ad928SBarry Smith 
6114b9ad928SBarry Smith    Level: intermediate
6124b9ad928SBarry Smith 
6134b9ad928SBarry Smith    Concepts: composing solvers
6144b9ad928SBarry Smith 
6154b9ad928SBarry Smith    Notes: To use a Krylov method inside the composite preconditioner, set the PCType of one or more
6164b9ad928SBarry Smith           inner PCs to be PCKSP.
6174b9ad928SBarry Smith           Using a Krylov method inside another Krylov method can be dangerous (you get divergence or
618b3ef52cdSBarry Smith           the incorrect answer) unless you use KSPFGMRES as the outer Krylov method
6194b9ad928SBarry Smith 
6204b9ad928SBarry Smith 
6214b9ad928SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
6224b9ad928SBarry Smith            PCSHELL, PCKSP, PCCompositeSetType(), PCCompositeSpecialSetAlpha(), PCCompositeAddPC(),
62349517cdeSBarry Smith            PCCompositeGetPC(), PCSetUseAmat()
6244b9ad928SBarry Smith 
6254b9ad928SBarry Smith M*/
6264b9ad928SBarry Smith 
6274b9ad928SBarry Smith #undef __FUNCT__
6284b9ad928SBarry Smith #define __FUNCT__ "PCCreate_Composite"
6298cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Composite(PC pc)
6304b9ad928SBarry Smith {
631dfbe8321SBarry Smith   PetscErrorCode ierr;
6324b9ad928SBarry Smith   PC_Composite   *jac;
6334b9ad928SBarry Smith 
6344b9ad928SBarry Smith   PetscFunctionBegin;
635b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
6362fa5cd67SKarl Rupp 
6374b9ad928SBarry Smith   pc->ops->apply           = PCApply_Composite_Additive;
6382533e041SBarry Smith   pc->ops->applytranspose  = PCApplyTranspose_Composite_Additive;
6394b9ad928SBarry Smith   pc->ops->setup           = PCSetUp_Composite;
64069d2c0f9SBarry Smith   pc->ops->reset           = PCReset_Composite;
6414b9ad928SBarry Smith   pc->ops->destroy         = PCDestroy_Composite;
6424b9ad928SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Composite;
6434b9ad928SBarry Smith   pc->ops->view            = PCView_Composite;
6444b9ad928SBarry Smith   pc->ops->applyrichardson = 0;
6454b9ad928SBarry Smith 
6464b9ad928SBarry Smith   pc->data   = (void*)jac;
6474b9ad928SBarry Smith   jac->type  = PC_COMPOSITE_ADDITIVE;
6484b9ad928SBarry Smith   jac->work1 = 0;
6494b9ad928SBarry Smith   jac->work2 = 0;
6504b9ad928SBarry Smith   jac->head  = 0;
6514b9ad928SBarry Smith 
652bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeSetType_C",PCCompositeSetType_Composite);CHKERRQ(ierr);
653c60c7ad4SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetType_C",PCCompositeGetType_Composite);CHKERRQ(ierr);
654bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeAddPC_C",PCCompositeAddPC_Composite);CHKERRQ(ierr);
6558e6eba06SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetNumberPC_C",PCCompositeGetNumberPC_Composite);CHKERRQ(ierr);
656bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetPC_C",PCCompositeGetPC_Composite);CHKERRQ(ierr);
657bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeSpecialSetAlpha_C",PCCompositeSpecialSetAlpha_Composite);CHKERRQ(ierr);
6584b9ad928SBarry Smith   PetscFunctionReturn(0);
6594b9ad928SBarry Smith }
6604b9ad928SBarry Smith 
661