xref: /petsc/src/ksp/pc/impls/composite/composite.c (revision 4416b707960d1402d451ea66f392b9e9d922d271)
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;
33450d59ebSPatrick Farrell 
34ce94432eSBarry Smith   if (!next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPC() or -pc_composite_pcs");
35450d59ebSPatrick Farrell 
36450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
37450d59ebSPatrick Farrell   while (next) {
38450d59ebSPatrick Farrell     ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
39450d59ebSPatrick Farrell     next = next->next;
40450d59ebSPatrick Farrell   }
41450d59ebSPatrick Farrell   next = jac->head;
42450d59ebSPatrick 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 
128450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
129450d59ebSPatrick Farrell   ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
130450d59ebSPatrick Farrell   ierr = PCSetReusePreconditioner(next->next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
131450d59ebSPatrick 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");
147450d59ebSPatrick Farrell 
148450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
149450d59ebSPatrick Farrell   while (next) {
150450d59ebSPatrick Farrell     ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
151450d59ebSPatrick Farrell     next = next->next;
152450d59ebSPatrick Farrell   }
153450d59ebSPatrick Farrell   next = jac->head;
154450d59ebSPatrick 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;
1925a78d018SMatthew G. Knepley   DM               dm;
1934b9ad928SBarry Smith 
1944b9ad928SBarry Smith   PetscFunctionBegin;
1954b9ad928SBarry Smith   if (!jac->work1) {
1962a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&jac->work1,0);CHKERRQ(ierr);
1974b9ad928SBarry Smith   }
1985a78d018SMatthew G. Knepley   ierr = PCGetDM(pc,&dm);CHKERRQ(ierr);
1994b9ad928SBarry Smith   while (next) {
2005a78d018SMatthew G. Knepley     ierr = PCSetDM(next->pc,dm);CHKERRQ(ierr);
20123ee1639SBarry Smith     ierr = PCSetOperators(next->pc,pc->mat,pc->pmat);CHKERRQ(ierr);
2024b9ad928SBarry Smith     next = next->next;
2034b9ad928SBarry Smith   }
2044b9ad928SBarry Smith   PetscFunctionReturn(0);
2054b9ad928SBarry Smith }
2064b9ad928SBarry Smith 
2074b9ad928SBarry Smith #undef __FUNCT__
20869d2c0f9SBarry Smith #define __FUNCT__ "PCReset_Composite"
20969d2c0f9SBarry Smith static PetscErrorCode PCReset_Composite(PC pc)
21069d2c0f9SBarry Smith {
21169d2c0f9SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
21269d2c0f9SBarry Smith   PetscErrorCode   ierr;
2135f48b12bSBarry Smith   PC_CompositeLink next = jac->head;
21469d2c0f9SBarry Smith 
21569d2c0f9SBarry Smith   PetscFunctionBegin;
21669d2c0f9SBarry Smith   while (next) {
21769d2c0f9SBarry Smith     ierr = PCReset(next->pc);CHKERRQ(ierr);
21869d2c0f9SBarry Smith     next = next->next;
21969d2c0f9SBarry Smith   }
2206bf464f9SBarry Smith   ierr = VecDestroy(&jac->work1);CHKERRQ(ierr);
2216bf464f9SBarry Smith   ierr = VecDestroy(&jac->work2);CHKERRQ(ierr);
22269d2c0f9SBarry Smith   PetscFunctionReturn(0);
22369d2c0f9SBarry Smith }
22469d2c0f9SBarry Smith 
22569d2c0f9SBarry Smith #undef __FUNCT__
2264b9ad928SBarry Smith #define __FUNCT__ "PCDestroy_Composite"
2276849ba73SBarry Smith static PetscErrorCode PCDestroy_Composite(PC pc)
2284b9ad928SBarry Smith {
2294b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
230dfbe8321SBarry Smith   PetscErrorCode   ierr;
231724c2c99SHong Zhang   PC_CompositeLink next = jac->head,next_tmp;
2324b9ad928SBarry Smith 
2334b9ad928SBarry Smith   PetscFunctionBegin;
23469d2c0f9SBarry Smith   ierr = PCReset_Composite(pc);CHKERRQ(ierr);
2354b9ad928SBarry Smith   while (next) {
2366bf464f9SBarry Smith     ierr     = PCDestroy(&next->pc);CHKERRQ(ierr);
237724c2c99SHong Zhang     next_tmp = next;
2384b9ad928SBarry Smith     next     = next->next;
239724c2c99SHong Zhang     ierr     = PetscFree(next_tmp);CHKERRQ(ierr);
2404b9ad928SBarry Smith   }
241c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2424b9ad928SBarry Smith   PetscFunctionReturn(0);
2434b9ad928SBarry Smith }
2444b9ad928SBarry Smith 
2454b9ad928SBarry Smith #undef __FUNCT__
2464b9ad928SBarry Smith #define __FUNCT__ "PCSetFromOptions_Composite"
247*4416b707SBarry Smith static PetscErrorCode PCSetFromOptions_Composite(PetscOptionItems *PetscOptionsObject,PC pc)
2484b9ad928SBarry Smith {
2494b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
250dfbe8321SBarry Smith   PetscErrorCode   ierr;
2519dcbbd2bSBarry Smith   PetscInt         nmax = 8,i;
2524b9ad928SBarry Smith   PC_CompositeLink next;
253e5999256SBarry Smith   char             *pcs[8];
254ace3abfcSBarry Smith   PetscBool        flg;
2554b9ad928SBarry Smith 
2564b9ad928SBarry Smith   PetscFunctionBegin;
257e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Composite preconditioner options");CHKERRQ(ierr);
2589dcbbd2bSBarry Smith   ierr = PetscOptionsEnum("-pc_composite_type","Type of composition","PCCompositeSetType",PCCompositeTypes,(PetscEnum)jac->type,(PetscEnum*)&jac->type,&flg);CHKERRQ(ierr);
25951f519a2SBarry Smith   if (flg) {
26051f519a2SBarry Smith     ierr = PCCompositeSetType(pc,jac->type);CHKERRQ(ierr);
26151f519a2SBarry Smith   }
2624b9ad928SBarry Smith   ierr = PetscOptionsStringArray("-pc_composite_pcs","List of composite solvers","PCCompositeAddPC",pcs,&nmax,&flg);CHKERRQ(ierr);
2634b9ad928SBarry Smith   if (flg) {
2644b9ad928SBarry Smith     for (i=0; i<nmax; i++) {
2654b9ad928SBarry Smith       ierr = PCCompositeAddPC(pc,pcs[i]);CHKERRQ(ierr);
266724c2c99SHong Zhang       ierr = PetscFree(pcs[i]);CHKERRQ(ierr);   /* deallocate string pcs[i], which is allocated in PetscOptionsStringArray() */
2674b9ad928SBarry Smith     }
2684b9ad928SBarry Smith   }
2694b9ad928SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2704b9ad928SBarry Smith 
2714b9ad928SBarry Smith   next = jac->head;
2724b9ad928SBarry Smith   while (next) {
2734b9ad928SBarry Smith     ierr = PCSetFromOptions(next->pc);CHKERRQ(ierr);
2744b9ad928SBarry Smith     next = next->next;
2754b9ad928SBarry Smith   }
2764b9ad928SBarry Smith   PetscFunctionReturn(0);
2774b9ad928SBarry Smith }
2784b9ad928SBarry Smith 
2794b9ad928SBarry Smith #undef __FUNCT__
2804b9ad928SBarry Smith #define __FUNCT__ "PCView_Composite"
2816849ba73SBarry Smith static PetscErrorCode PCView_Composite(PC pc,PetscViewer viewer)
2824b9ad928SBarry Smith {
2834b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
284dfbe8321SBarry Smith   PetscErrorCode   ierr;
2854b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
286ace3abfcSBarry Smith   PetscBool        iascii;
2874b9ad928SBarry Smith 
2884b9ad928SBarry Smith   PetscFunctionBegin;
289251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
29032077d6dSBarry Smith   if (iascii) {
2919dcbbd2bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Composite PC type - %s\n",PCCompositeTypes[jac->type]);CHKERRQ(ierr);
2924b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"PCs on composite preconditioner follow\n");CHKERRQ(ierr);
2934b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr);
2944b9ad928SBarry Smith   }
29532077d6dSBarry Smith   if (iascii) {
2964b9ad928SBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2974b9ad928SBarry Smith   }
2984b9ad928SBarry Smith   while (next) {
2994b9ad928SBarry Smith     ierr = PCView(next->pc,viewer);CHKERRQ(ierr);
3004b9ad928SBarry Smith     next = next->next;
3014b9ad928SBarry Smith   }
30232077d6dSBarry Smith   if (iascii) {
3034b9ad928SBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3044b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr);
3054b9ad928SBarry Smith   }
3064b9ad928SBarry Smith   PetscFunctionReturn(0);
3074b9ad928SBarry Smith }
3084b9ad928SBarry Smith 
3094b9ad928SBarry Smith /* ------------------------------------------------------------------------------*/
3104b9ad928SBarry Smith 
3114b9ad928SBarry Smith #undef __FUNCT__
3124b9ad928SBarry Smith #define __FUNCT__ "PCCompositeSpecialSetAlpha_Composite"
3131e6b0712SBarry Smith static PetscErrorCode  PCCompositeSpecialSetAlpha_Composite(PC pc,PetscScalar alpha)
3144b9ad928SBarry Smith {
3154b9ad928SBarry Smith   PC_Composite *jac = (PC_Composite*)pc->data;
3165fd66863SKarl Rupp 
3174b9ad928SBarry Smith   PetscFunctionBegin;
3184b9ad928SBarry Smith   jac->alpha = alpha;
3194b9ad928SBarry Smith   PetscFunctionReturn(0);
3204b9ad928SBarry Smith }
3214b9ad928SBarry Smith 
3224b9ad928SBarry Smith #undef __FUNCT__
3234b9ad928SBarry Smith #define __FUNCT__ "PCCompositeSetType_Composite"
3241e6b0712SBarry Smith static PetscErrorCode  PCCompositeSetType_Composite(PC pc,PCCompositeType type)
3254b9ad928SBarry Smith {
326fad69fbaSJed Brown   PC_Composite *jac = (PC_Composite*)pc->data;
327fad69fbaSJed Brown 
3284b9ad928SBarry Smith   PetscFunctionBegin;
3294b9ad928SBarry Smith   if (type == PC_COMPOSITE_ADDITIVE) {
3304b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Additive;
3312533e041SBarry Smith     pc->ops->applytranspose = PCApplyTranspose_Composite_Additive;
332421e10b8SBarry Smith   } else if (type ==  PC_COMPOSITE_MULTIPLICATIVE || type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
3334b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Multiplicative;
3342533e041SBarry Smith     pc->ops->applytranspose = PCApplyTranspose_Composite_Multiplicative;
3354b9ad928SBarry Smith   } else if (type ==  PC_COMPOSITE_SPECIAL) {
3364b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Special;
3370298fd71SBarry Smith     pc->ops->applytranspose = NULL;
338ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unkown composite preconditioner type");
339fad69fbaSJed Brown   jac->type = type;
3404b9ad928SBarry Smith   PetscFunctionReturn(0);
3414b9ad928SBarry Smith }
3424b9ad928SBarry Smith 
3434b9ad928SBarry Smith #undef __FUNCT__
344c60c7ad4SBarry Smith #define __FUNCT__ "PCCompositeGetType_Composite"
345c60c7ad4SBarry Smith static PetscErrorCode  PCCompositeGetType_Composite(PC pc,PCCompositeType *type)
346c60c7ad4SBarry Smith {
347c60c7ad4SBarry Smith   PC_Composite *jac = (PC_Composite*)pc->data;
348c60c7ad4SBarry Smith 
349c60c7ad4SBarry Smith   PetscFunctionBegin;
350c60c7ad4SBarry Smith   *type = jac->type;
351c60c7ad4SBarry Smith   PetscFunctionReturn(0);
352c60c7ad4SBarry Smith }
353c60c7ad4SBarry Smith 
354c60c7ad4SBarry Smith #undef __FUNCT__
3554b9ad928SBarry Smith #define __FUNCT__ "PCCompositeAddPC_Composite"
3561e6b0712SBarry Smith static PetscErrorCode  PCCompositeAddPC_Composite(PC pc,PCType type)
3574b9ad928SBarry Smith {
3584b9ad928SBarry Smith   PC_Composite     *jac;
3595a9f2f41SSatish Balay   PC_CompositeLink next,ilink;
360dfbe8321SBarry Smith   PetscErrorCode   ierr;
36179416396SBarry Smith   PetscInt         cnt = 0;
3622dcb1b2aSMatthew Knepley   const char       *prefix;
3632dcb1b2aSMatthew Knepley   char             newprefix[8];
3644b9ad928SBarry Smith 
3654b9ad928SBarry Smith   PetscFunctionBegin;
366b00a9115SJed Brown   ierr        = PetscNewLog(pc,&ilink);CHKERRQ(ierr);
3675a9f2f41SSatish Balay   ilink->next = 0;
368ce94432eSBarry Smith   ierr        = PCCreate(PetscObjectComm((PetscObject)pc),&ilink->pc);CHKERRQ(ierr);
369ace3abfcSBarry Smith   ierr        = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilink->pc);CHKERRQ(ierr);
3704b9ad928SBarry Smith 
3714b9ad928SBarry Smith   jac  = (PC_Composite*)pc->data;
3724b9ad928SBarry Smith   next = jac->head;
3734b9ad928SBarry Smith   if (!next) {
3745a9f2f41SSatish Balay     jac->head       = ilink;
3750298fd71SBarry Smith     ilink->previous = NULL;
3764b9ad928SBarry Smith   } else {
3774b9ad928SBarry Smith     cnt++;
3784b9ad928SBarry Smith     while (next->next) {
3794b9ad928SBarry Smith       next = next->next;
3804b9ad928SBarry Smith       cnt++;
3814b9ad928SBarry Smith     }
3825a9f2f41SSatish Balay     next->next      = ilink;
383421e10b8SBarry Smith     ilink->previous = next;
3844b9ad928SBarry Smith   }
3854b9ad928SBarry Smith   ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
3865a9f2f41SSatish Balay   ierr = PCSetOptionsPrefix(ilink->pc,prefix);CHKERRQ(ierr);
38713f74950SBarry Smith   sprintf(newprefix,"sub_%d_",(int)cnt);
3885a9f2f41SSatish Balay   ierr = PCAppendOptionsPrefix(ilink->pc,newprefix);CHKERRQ(ierr);
3894b9ad928SBarry Smith   /* type is set after prefix, because some methods may modify prefix, e.g. pcksp */
3905a9f2f41SSatish Balay   ierr = PCSetType(ilink->pc,type);CHKERRQ(ierr);
3914b9ad928SBarry Smith   PetscFunctionReturn(0);
3924b9ad928SBarry Smith }
3934b9ad928SBarry Smith 
3944b9ad928SBarry Smith #undef __FUNCT__
3958e6eba06SBarry Smith #define __FUNCT__ "PCCompositeGetNumberPC_Composite"
3968e6eba06SBarry Smith static PetscErrorCode  PCCompositeGetNumberPC_Composite(PC pc,PetscInt *n)
3978e6eba06SBarry Smith {
3988e6eba06SBarry Smith   PC_Composite     *jac;
3998e6eba06SBarry Smith   PC_CompositeLink next;
4008e6eba06SBarry Smith 
4018e6eba06SBarry Smith   PetscFunctionBegin;
4028e6eba06SBarry Smith   jac  = (PC_Composite*)pc->data;
4038e6eba06SBarry Smith   next = jac->head;
4048e6eba06SBarry Smith   *n = 0;
4058e6eba06SBarry Smith   while (next) {
4068e6eba06SBarry Smith     next = next->next;
4078e6eba06SBarry Smith     (*n) ++;
4088e6eba06SBarry Smith   }
4098e6eba06SBarry Smith   PetscFunctionReturn(0);
4108e6eba06SBarry Smith }
4118e6eba06SBarry Smith 
4128e6eba06SBarry Smith #undef __FUNCT__
4134b9ad928SBarry Smith #define __FUNCT__ "PCCompositeGetPC_Composite"
4141e6b0712SBarry Smith static PetscErrorCode  PCCompositeGetPC_Composite(PC pc,PetscInt n,PC *subpc)
4154b9ad928SBarry Smith {
4164b9ad928SBarry Smith   PC_Composite     *jac;
4174b9ad928SBarry Smith   PC_CompositeLink next;
41879416396SBarry Smith   PetscInt         i;
4194b9ad928SBarry Smith 
4204b9ad928SBarry Smith   PetscFunctionBegin;
4214b9ad928SBarry Smith   jac  = (PC_Composite*)pc->data;
4224b9ad928SBarry Smith   next = jac->head;
4234b9ad928SBarry Smith   for (i=0; i<n; i++) {
424ce94432eSBarry Smith     if (!next->next) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Not enough PCs in composite preconditioner");
4254b9ad928SBarry Smith     next = next->next;
4264b9ad928SBarry Smith   }
4274b9ad928SBarry Smith   *subpc = next->pc;
4284b9ad928SBarry Smith   PetscFunctionReturn(0);
4294b9ad928SBarry Smith }
4304b9ad928SBarry Smith 
4314b9ad928SBarry Smith /* -------------------------------------------------------------------------------- */
4324b9ad928SBarry Smith #undef __FUNCT__
4334b9ad928SBarry Smith #define __FUNCT__ "PCCompositeSetType"
434f39d8e23SSatish Balay /*@
4354b9ad928SBarry Smith    PCCompositeSetType - Sets the type of composite preconditioner.
4364b9ad928SBarry Smith 
437ad4df100SBarry Smith    Logically Collective on PC
4384b9ad928SBarry Smith 
439c60c7ad4SBarry Smith    Input Parameters:
4402a6744ebSBarry Smith +  pc - the preconditioner context
4412a6744ebSBarry Smith -  type - PC_COMPOSITE_ADDITIVE (default), PC_COMPOSITE_MULTIPLICATIVE, PC_COMPOSITE_SPECIAL
4424b9ad928SBarry Smith 
4434b9ad928SBarry Smith    Options Database Key:
4444b9ad928SBarry Smith .  -pc_composite_type <type: one of multiplicative, additive, special> - Sets composite preconditioner type
4454b9ad928SBarry Smith 
4464b9ad928SBarry Smith    Level: Developer
4474b9ad928SBarry Smith 
4484b9ad928SBarry Smith .keywords: PC, set, type, composite preconditioner, additive, multiplicative
4494b9ad928SBarry Smith @*/
4507087cfbeSBarry Smith PetscErrorCode  PCCompositeSetType(PC pc,PCCompositeType type)
4514b9ad928SBarry Smith {
4527bb14e67SBarry Smith   PetscErrorCode ierr;
4534b9ad928SBarry Smith 
4544b9ad928SBarry Smith   PetscFunctionBegin;
4550700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
456c5eb9154SBarry Smith   PetscValidLogicalCollectiveEnum(pc,type,2);
4577bb14e67SBarry Smith   ierr = PetscTryMethod(pc,"PCCompositeSetType_C",(PC,PCCompositeType),(pc,type));CHKERRQ(ierr);
4584b9ad928SBarry Smith   PetscFunctionReturn(0);
4594b9ad928SBarry Smith }
4604b9ad928SBarry Smith 
4614b9ad928SBarry Smith #undef __FUNCT__
462c60c7ad4SBarry Smith #define __FUNCT__ "PCCompositeGetType"
463c60c7ad4SBarry Smith /*@
464721f67b5SBarry Smith    PCCompositeGetType - Gets the type of composite preconditioner.
465c60c7ad4SBarry Smith 
466c60c7ad4SBarry Smith    Logically Collective on PC
467c60c7ad4SBarry Smith 
468c60c7ad4SBarry Smith    Input Parameter:
469c60c7ad4SBarry Smith .  pc - the preconditioner context
470c60c7ad4SBarry Smith 
471c60c7ad4SBarry Smith    Output Parameter:
472c60c7ad4SBarry Smith .  type - PC_COMPOSITE_ADDITIVE (default), PC_COMPOSITE_MULTIPLICATIVE, PC_COMPOSITE_SPECIAL
473c60c7ad4SBarry Smith 
474c60c7ad4SBarry Smith    Options Database Key:
475c60c7ad4SBarry Smith .  -pc_composite_type <type: one of multiplicative, additive, special> - Sets composite preconditioner type
476c60c7ad4SBarry Smith 
477c60c7ad4SBarry Smith    Level: Developer
478c60c7ad4SBarry Smith 
479c60c7ad4SBarry Smith .keywords: PC, set, type, composite preconditioner, additive, multiplicative
480c60c7ad4SBarry Smith @*/
481c60c7ad4SBarry Smith PetscErrorCode  PCCompositeGetType(PC pc,PCCompositeType *type)
482c60c7ad4SBarry Smith {
483c60c7ad4SBarry Smith   PetscErrorCode ierr;
484c60c7ad4SBarry Smith 
485c60c7ad4SBarry Smith   PetscFunctionBegin;
486c60c7ad4SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
487c60c7ad4SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetType_C",(PC,PCCompositeType*),(pc,type));CHKERRQ(ierr);
488c60c7ad4SBarry Smith   PetscFunctionReturn(0);
489c60c7ad4SBarry Smith }
490c60c7ad4SBarry Smith 
491c60c7ad4SBarry Smith #undef __FUNCT__
4924b9ad928SBarry Smith #define __FUNCT__ "PCCompositeSpecialSetAlpha"
493f39d8e23SSatish Balay /*@
4944b9ad928SBarry Smith    PCCompositeSpecialSetAlpha - Sets alpha for the special composite preconditioner
4954b9ad928SBarry Smith      for alphaI + R + S
4964b9ad928SBarry Smith 
497ad4df100SBarry Smith    Logically Collective on PC
4984b9ad928SBarry Smith 
4994b9ad928SBarry Smith    Input Parameter:
5004b9ad928SBarry Smith +  pc - the preconditioner context
5014b9ad928SBarry Smith -  alpha - scale on identity
5024b9ad928SBarry Smith 
5034b9ad928SBarry Smith    Level: Developer
5044b9ad928SBarry Smith 
5054b9ad928SBarry Smith .keywords: PC, set, type, composite preconditioner, additive, multiplicative
5064b9ad928SBarry Smith @*/
5077087cfbeSBarry Smith PetscErrorCode  PCCompositeSpecialSetAlpha(PC pc,PetscScalar alpha)
5084b9ad928SBarry Smith {
5094ac538c5SBarry Smith   PetscErrorCode ierr;
5104b9ad928SBarry Smith 
5114b9ad928SBarry Smith   PetscFunctionBegin;
5120700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
513c5eb9154SBarry Smith   PetscValidLogicalCollectiveScalar(pc,alpha,2);
5144ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCCompositeSpecialSetAlpha_C",(PC,PetscScalar),(pc,alpha));CHKERRQ(ierr);
5154b9ad928SBarry Smith   PetscFunctionReturn(0);
5164b9ad928SBarry Smith }
5174b9ad928SBarry Smith 
5184b9ad928SBarry Smith #undef __FUNCT__
5194b9ad928SBarry Smith #define __FUNCT__ "PCCompositeAddPC"
5204b9ad928SBarry Smith /*@C
5214b9ad928SBarry Smith    PCCompositeAddPC - Adds another PC to the composite PC.
5224b9ad928SBarry Smith 
5234b9ad928SBarry Smith    Collective on PC
5244b9ad928SBarry Smith 
5254b9ad928SBarry Smith    Input Parameters:
5262a6744ebSBarry Smith +  pc - the preconditioner context
5272a6744ebSBarry Smith -  type - the type of the new preconditioner
5284b9ad928SBarry Smith 
5294b9ad928SBarry Smith    Level: Developer
5304b9ad928SBarry Smith 
5314b9ad928SBarry Smith .keywords: PC, composite preconditioner, add
5324b9ad928SBarry Smith @*/
53319fd82e9SBarry Smith PetscErrorCode  PCCompositeAddPC(PC pc,PCType type)
5344b9ad928SBarry Smith {
5354ac538c5SBarry Smith   PetscErrorCode ierr;
5364b9ad928SBarry Smith 
5374b9ad928SBarry Smith   PetscFunctionBegin;
5380700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
53919fd82e9SBarry Smith   ierr = PetscTryMethod(pc,"PCCompositeAddPC_C",(PC,PCType),(pc,type));CHKERRQ(ierr);
5404b9ad928SBarry Smith   PetscFunctionReturn(0);
5414b9ad928SBarry Smith }
5424b9ad928SBarry Smith 
5434b9ad928SBarry Smith #undef __FUNCT__
5448e6eba06SBarry Smith #define __FUNCT__ "PCCompositeGetNumberPC"
5458e6eba06SBarry Smith /*@
5468e6eba06SBarry Smith    PCCompositeGetNumberPC - Gets the number of PC objects in the composite PC.
5478e6eba06SBarry Smith 
5488e6eba06SBarry Smith    Not Collective
5498e6eba06SBarry Smith 
5508e6eba06SBarry Smith    Input Parameter:
5518e6eba06SBarry Smith .  pc - the preconditioner context
5528e6eba06SBarry Smith 
5538e6eba06SBarry Smith    Output Parameter:
5548e6eba06SBarry Smith .  num - the number of sub pcs
5558e6eba06SBarry Smith 
5568e6eba06SBarry Smith    Level: Developer
5578e6eba06SBarry Smith 
5588e6eba06SBarry Smith .keywords: PC, get, composite preconditioner, sub preconditioner
5598e6eba06SBarry Smith 
5608e6eba06SBarry Smith .seealso: PCCompositeGetPC()
5618e6eba06SBarry Smith @*/
5628e6eba06SBarry Smith PetscErrorCode  PCCompositeGetNumberPC(PC pc,PetscInt *num)
5638e6eba06SBarry Smith {
5648e6eba06SBarry Smith   PetscErrorCode ierr;
5658e6eba06SBarry Smith 
5668e6eba06SBarry Smith   PetscFunctionBegin;
5678e6eba06SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5688e6eba06SBarry Smith   PetscValidIntPointer(num,2);
5698e6eba06SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetNumberPC_C",(PC,PetscInt*),(pc,num));CHKERRQ(ierr);
5708e6eba06SBarry Smith   PetscFunctionReturn(0);
5718e6eba06SBarry Smith }
5728e6eba06SBarry Smith 
5738e6eba06SBarry Smith #undef __FUNCT__
5744b9ad928SBarry Smith #define __FUNCT__ "PCCompositeGetPC"
575f39d8e23SSatish Balay /*@
5764b9ad928SBarry Smith    PCCompositeGetPC - Gets one of the PC objects in the composite PC.
5774b9ad928SBarry Smith 
5784b9ad928SBarry Smith    Not Collective
5794b9ad928SBarry Smith 
5804b9ad928SBarry Smith    Input Parameter:
5812a6744ebSBarry Smith +  pc - the preconditioner context
5822a6744ebSBarry Smith -  n - the number of the pc requested
5834b9ad928SBarry Smith 
5844b9ad928SBarry Smith    Output Parameters:
5854b9ad928SBarry Smith .  subpc - the PC requested
5864b9ad928SBarry Smith 
5874b9ad928SBarry Smith    Level: Developer
5884b9ad928SBarry Smith 
5894b9ad928SBarry Smith .keywords: PC, get, composite preconditioner, sub preconditioner
5904b9ad928SBarry Smith 
5918e6eba06SBarry Smith .seealso: PCCompositeAddPC(), PCCompositeGetNumberPC()
5924b9ad928SBarry Smith @*/
5937087cfbeSBarry Smith PetscErrorCode  PCCompositeGetPC(PC pc,PetscInt n,PC *subpc)
5944b9ad928SBarry Smith {
5954ac538c5SBarry Smith   PetscErrorCode ierr;
5964b9ad928SBarry Smith 
5974b9ad928SBarry Smith   PetscFunctionBegin;
5980700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5994482741eSBarry Smith   PetscValidPointer(subpc,3);
6004ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetPC_C",(PC,PetscInt,PC*),(pc,n,subpc));CHKERRQ(ierr);
6014b9ad928SBarry Smith   PetscFunctionReturn(0);
6024b9ad928SBarry Smith }
6034b9ad928SBarry Smith 
6044b9ad928SBarry Smith /* -------------------------------------------------------------------------------------------*/
6054b9ad928SBarry Smith 
6064b9ad928SBarry Smith /*MC
6074b9ad928SBarry Smith      PCCOMPOSITE - Build a preconditioner by composing together several preconditioners
6084b9ad928SBarry Smith 
6094b9ad928SBarry Smith    Options Database Keys:
6102eab2d5bSJungho Lee +  -pc_composite_type <type: one of multiplicative, additive, symmetric_multiplicative, special> - Sets composite preconditioner type
61149517cdeSBarry Smith .  -pc_use_amat - Activates PCSetUseAmat()
61251f519a2SBarry Smith -  -pc_composite_pcs - <pc0,pc1,...> list of PCs to compose
6134b9ad928SBarry Smith 
6144b9ad928SBarry Smith    Level: intermediate
6154b9ad928SBarry Smith 
6164b9ad928SBarry Smith    Concepts: composing solvers
6174b9ad928SBarry Smith 
6184b9ad928SBarry Smith    Notes: To use a Krylov method inside the composite preconditioner, set the PCType of one or more
6194b9ad928SBarry Smith           inner PCs to be PCKSP.
6204b9ad928SBarry Smith           Using a Krylov method inside another Krylov method can be dangerous (you get divergence or
621b3ef52cdSBarry Smith           the incorrect answer) unless you use KSPFGMRES as the outer Krylov method
6224b9ad928SBarry Smith 
6234b9ad928SBarry Smith 
6244b9ad928SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
6254b9ad928SBarry Smith            PCSHELL, PCKSP, PCCompositeSetType(), PCCompositeSpecialSetAlpha(), PCCompositeAddPC(),
62649517cdeSBarry Smith            PCCompositeGetPC(), PCSetUseAmat()
6274b9ad928SBarry Smith 
6284b9ad928SBarry Smith M*/
6294b9ad928SBarry Smith 
6304b9ad928SBarry Smith #undef __FUNCT__
6314b9ad928SBarry Smith #define __FUNCT__ "PCCreate_Composite"
6328cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Composite(PC pc)
6334b9ad928SBarry Smith {
634dfbe8321SBarry Smith   PetscErrorCode ierr;
6354b9ad928SBarry Smith   PC_Composite   *jac;
6364b9ad928SBarry Smith 
6374b9ad928SBarry Smith   PetscFunctionBegin;
638b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
6392fa5cd67SKarl Rupp 
6404b9ad928SBarry Smith   pc->ops->apply           = PCApply_Composite_Additive;
6412533e041SBarry Smith   pc->ops->applytranspose  = PCApplyTranspose_Composite_Additive;
6424b9ad928SBarry Smith   pc->ops->setup           = PCSetUp_Composite;
64369d2c0f9SBarry Smith   pc->ops->reset           = PCReset_Composite;
6444b9ad928SBarry Smith   pc->ops->destroy         = PCDestroy_Composite;
6454b9ad928SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Composite;
6464b9ad928SBarry Smith   pc->ops->view            = PCView_Composite;
6474b9ad928SBarry Smith   pc->ops->applyrichardson = 0;
6484b9ad928SBarry Smith 
6494b9ad928SBarry Smith   pc->data   = (void*)jac;
6504b9ad928SBarry Smith   jac->type  = PC_COMPOSITE_ADDITIVE;
6514b9ad928SBarry Smith   jac->work1 = 0;
6524b9ad928SBarry Smith   jac->work2 = 0;
6534b9ad928SBarry Smith   jac->head  = 0;
6544b9ad928SBarry Smith 
655bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeSetType_C",PCCompositeSetType_Composite);CHKERRQ(ierr);
656c60c7ad4SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetType_C",PCCompositeGetType_Composite);CHKERRQ(ierr);
657bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeAddPC_C",PCCompositeAddPC_Composite);CHKERRQ(ierr);
6588e6eba06SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetNumberPC_C",PCCompositeGetNumberPC_Composite);CHKERRQ(ierr);
659bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetPC_C",PCCompositeGetPC_Composite);CHKERRQ(ierr);
660bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeSpecialSetAlpha_C",PCCompositeSpecialSetAlpha_Composite);CHKERRQ(ierr);
6614b9ad928SBarry Smith   PetscFunctionReturn(0);
6624b9ad928SBarry Smith }
6634b9ad928SBarry Smith 
664