xref: /petsc/src/ksp/pc/impls/composite/composite.c (revision 2c71b3e237ead271e4f3aa1505f92bf476e3413d)
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 
236849ba73SBarry Smith static PetscErrorCode PCApply_Composite_Multiplicative(PC pc,Vec x,Vec y)
244b9ad928SBarry Smith {
25dfbe8321SBarry Smith   PetscErrorCode   ierr;
264b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
274b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
284b9ad928SBarry Smith   Mat              mat  = pc->pmat;
294b9ad928SBarry Smith 
304b9ad928SBarry Smith   PetscFunctionBegin;
31450d59ebSPatrick Farrell 
32*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!next,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
33450d59ebSPatrick Farrell 
34450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
35450d59ebSPatrick Farrell   while (next) {
36450d59ebSPatrick Farrell     ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
37450d59ebSPatrick Farrell     next = next->next;
38450d59ebSPatrick Farrell   }
39450d59ebSPatrick Farrell   next = jac->head;
40450d59ebSPatrick Farrell 
414b9ad928SBarry Smith   if (next->next && !jac->work2) { /* allocate second work vector */
424b9ad928SBarry Smith     ierr = VecDuplicate(jac->work1,&jac->work2);CHKERRQ(ierr);
434b9ad928SBarry Smith   }
4449517cdeSBarry Smith   if (pc->useAmat) mat = pc->mat;
4509b21952SJed Brown   ierr = PCApply(next->pc,x,y);CHKERRQ(ierr);                      /* y <- B x */
464b9ad928SBarry Smith   while (next->next) {
474b9ad928SBarry Smith     next = next->next;
4809b21952SJed Brown     ierr = MatMult(mat,y,jac->work1);CHKERRQ(ierr);                /* work1 <- A y */
4909b21952SJed Brown     ierr = VecWAXPY(jac->work2,-1.0,jac->work1,x);CHKERRQ(ierr);   /* work2 <- x - work1 */
5009b21952SJed Brown     ierr = PCApply(next->pc,jac->work2,jac->work1);CHKERRQ(ierr);  /* work1 <- C work2 */
5109b21952SJed 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 */
524b9ad928SBarry Smith   }
53421e10b8SBarry Smith   if (jac->type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
54421e10b8SBarry Smith     while (next->previous) {
55421e10b8SBarry Smith       next = next->previous;
56421e10b8SBarry Smith       ierr = MatMult(mat,y,jac->work1);CHKERRQ(ierr);
57421e10b8SBarry Smith       ierr = VecWAXPY(jac->work2,-1.0,jac->work1,x);CHKERRQ(ierr);
58421e10b8SBarry Smith       ierr = PCApply(next->pc,jac->work2,jac->work1);CHKERRQ(ierr);
59421e10b8SBarry Smith       ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
60421e10b8SBarry Smith     }
61421e10b8SBarry Smith   }
624b9ad928SBarry Smith   PetscFunctionReturn(0);
634b9ad928SBarry Smith }
644b9ad928SBarry Smith 
652533e041SBarry Smith static PetscErrorCode PCApplyTranspose_Composite_Multiplicative(PC pc,Vec x,Vec y)
662533e041SBarry Smith {
672533e041SBarry Smith   PetscErrorCode   ierr;
682533e041SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
692533e041SBarry Smith   PC_CompositeLink next = jac->head;
702533e041SBarry Smith   Mat              mat  = pc->pmat;
712533e041SBarry Smith 
722533e041SBarry Smith   PetscFunctionBegin;
73*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!next,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
742533e041SBarry Smith   if (next->next && !jac->work2) { /* allocate second work vector */
752533e041SBarry Smith     ierr = VecDuplicate(jac->work1,&jac->work2);CHKERRQ(ierr);
762533e041SBarry Smith   }
7749517cdeSBarry Smith   if (pc->useAmat) mat = pc->mat;
782533e041SBarry Smith   /* locate last PC */
792533e041SBarry Smith   while (next->next) {
802533e041SBarry Smith     next = next->next;
812533e041SBarry Smith   }
822533e041SBarry Smith   ierr = PCApplyTranspose(next->pc,x,y);CHKERRQ(ierr);
832533e041SBarry Smith   while (next->previous) {
842533e041SBarry Smith     next = next->previous;
852533e041SBarry Smith     ierr = MatMultTranspose(mat,y,jac->work1);CHKERRQ(ierr);
862533e041SBarry Smith     ierr = VecWAXPY(jac->work2,-1.0,jac->work1,x);CHKERRQ(ierr);
872533e041SBarry Smith     ierr = PCApplyTranspose(next->pc,jac->work2,jac->work1);CHKERRQ(ierr);
882533e041SBarry Smith     ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
892533e041SBarry Smith   }
902533e041SBarry Smith   if (jac->type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
912533e041SBarry Smith     next = jac->head;
922533e041SBarry Smith     while (next->next) {
932533e041SBarry Smith       next = next->next;
942533e041SBarry Smith       ierr = MatMultTranspose(mat,y,jac->work1);CHKERRQ(ierr);
952533e041SBarry Smith       ierr = VecWAXPY(jac->work2,-1.0,jac->work1,x);CHKERRQ(ierr);
962533e041SBarry Smith       ierr = PCApplyTranspose(next->pc,jac->work2,jac->work1);CHKERRQ(ierr);
972533e041SBarry Smith       ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
982533e041SBarry Smith     }
992533e041SBarry Smith   }
1002533e041SBarry Smith   PetscFunctionReturn(0);
1012533e041SBarry Smith }
1022533e041SBarry Smith 
1034b9ad928SBarry Smith /*
1044b9ad928SBarry Smith     This is very special for a matrix of the form alpha I + R + S
1054b9ad928SBarry Smith where first preconditioner is built from alpha I + S and second from
1064b9ad928SBarry Smith alpha I + R
1074b9ad928SBarry Smith */
1086849ba73SBarry Smith static PetscErrorCode PCApply_Composite_Special(PC pc,Vec x,Vec y)
1094b9ad928SBarry Smith {
110dfbe8321SBarry Smith   PetscErrorCode   ierr;
1114b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
1124b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1134b9ad928SBarry Smith 
1144b9ad928SBarry Smith   PetscFunctionBegin;
115*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!next,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
116*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!next->next || next->next->next,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Special composite preconditioners requires exactly two PCs");
1174b9ad928SBarry Smith 
118450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
119450d59ebSPatrick Farrell   ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
120450d59ebSPatrick Farrell   ierr = PCSetReusePreconditioner(next->next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
121450d59ebSPatrick Farrell 
122d8fd42c4SBarry Smith   ierr = PCApply(next->pc,x,jac->work1);CHKERRQ(ierr);
123d8fd42c4SBarry Smith   ierr = PCApply(next->next->pc,jac->work1,y);CHKERRQ(ierr);
1244b9ad928SBarry Smith   PetscFunctionReturn(0);
1254b9ad928SBarry Smith }
1264b9ad928SBarry Smith 
1276849ba73SBarry Smith static PetscErrorCode PCApply_Composite_Additive(PC pc,Vec x,Vec y)
1284b9ad928SBarry Smith {
129dfbe8321SBarry Smith   PetscErrorCode   ierr;
1304b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
1314b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1324b9ad928SBarry Smith 
1334b9ad928SBarry Smith   PetscFunctionBegin;
134*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!next,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
135450d59ebSPatrick Farrell 
136450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
137450d59ebSPatrick Farrell   while (next) {
138450d59ebSPatrick Farrell     ierr = PCSetReusePreconditioner(next->pc,pc->reusepreconditioner);CHKERRQ(ierr);
139450d59ebSPatrick Farrell     next = next->next;
140450d59ebSPatrick Farrell   }
141450d59ebSPatrick Farrell   next = jac->head;
142450d59ebSPatrick Farrell 
143d8fd42c4SBarry Smith   ierr = PCApply(next->pc,x,y);CHKERRQ(ierr);
1444b9ad928SBarry Smith   while (next->next) {
1454b9ad928SBarry Smith     next = next->next;
146d8fd42c4SBarry Smith     ierr = PCApply(next->pc,x,jac->work1);CHKERRQ(ierr);
147efb30889SBarry Smith     ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
1484b9ad928SBarry Smith   }
1494b9ad928SBarry Smith   PetscFunctionReturn(0);
1504b9ad928SBarry Smith }
1514b9ad928SBarry Smith 
1522533e041SBarry Smith static PetscErrorCode PCApplyTranspose_Composite_Additive(PC pc,Vec x,Vec y)
1532533e041SBarry Smith {
1542533e041SBarry Smith   PetscErrorCode   ierr;
1552533e041SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
1562533e041SBarry Smith   PC_CompositeLink next = jac->head;
1572533e041SBarry Smith 
1582533e041SBarry Smith   PetscFunctionBegin;
159*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!next,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
1602533e041SBarry Smith   ierr = PCApplyTranspose(next->pc,x,y);CHKERRQ(ierr);
1612533e041SBarry Smith   while (next->next) {
1622533e041SBarry Smith     next = next->next;
1632533e041SBarry Smith     ierr = PCApplyTranspose(next->pc,x,jac->work1);CHKERRQ(ierr);
1642533e041SBarry Smith     ierr = VecAXPY(y,1.0,jac->work1);CHKERRQ(ierr);
1652533e041SBarry Smith   }
1662533e041SBarry Smith   PetscFunctionReturn(0);
1672533e041SBarry Smith }
1682533e041SBarry Smith 
1696849ba73SBarry Smith static PetscErrorCode PCSetUp_Composite(PC pc)
1704b9ad928SBarry Smith {
171dfbe8321SBarry Smith   PetscErrorCode   ierr;
1724b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
1734b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1745a78d018SMatthew G. Knepley   DM               dm;
1754b9ad928SBarry Smith 
1764b9ad928SBarry Smith   PetscFunctionBegin;
1774b9ad928SBarry Smith   if (!jac->work1) {
1780a545947SLisandro Dalcin     ierr = MatCreateVecs(pc->pmat,&jac->work1,NULL);CHKERRQ(ierr);
1794b9ad928SBarry Smith   }
1805a78d018SMatthew G. Knepley   ierr = PCGetDM(pc,&dm);CHKERRQ(ierr);
1814b9ad928SBarry Smith   while (next) {
1822b1d202aSBarry Smith     if (!next->pc->dm) {
1835a78d018SMatthew G. Knepley       ierr = PCSetDM(next->pc,dm);CHKERRQ(ierr);
1842b1d202aSBarry Smith     }
1852b1d202aSBarry Smith     if (!next->pc->mat) {
18623ee1639SBarry Smith       ierr = PCSetOperators(next->pc,pc->mat,pc->pmat);CHKERRQ(ierr);
1872b1d202aSBarry Smith     }
1884b9ad928SBarry Smith     next = next->next;
1894b9ad928SBarry Smith   }
1904b9ad928SBarry Smith   PetscFunctionReturn(0);
1914b9ad928SBarry Smith }
1924b9ad928SBarry Smith 
19369d2c0f9SBarry Smith static PetscErrorCode PCReset_Composite(PC pc)
19469d2c0f9SBarry Smith {
19569d2c0f9SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
19669d2c0f9SBarry Smith   PetscErrorCode   ierr;
1975f48b12bSBarry Smith   PC_CompositeLink next = jac->head;
19869d2c0f9SBarry Smith 
19969d2c0f9SBarry Smith   PetscFunctionBegin;
20069d2c0f9SBarry Smith   while (next) {
20169d2c0f9SBarry Smith     ierr = PCReset(next->pc);CHKERRQ(ierr);
20269d2c0f9SBarry Smith     next = next->next;
20369d2c0f9SBarry Smith   }
2046bf464f9SBarry Smith   ierr = VecDestroy(&jac->work1);CHKERRQ(ierr);
2056bf464f9SBarry Smith   ierr = VecDestroy(&jac->work2);CHKERRQ(ierr);
20669d2c0f9SBarry Smith   PetscFunctionReturn(0);
20769d2c0f9SBarry Smith }
20869d2c0f9SBarry Smith 
2096849ba73SBarry Smith static PetscErrorCode PCDestroy_Composite(PC pc)
2104b9ad928SBarry Smith {
2114b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
212dfbe8321SBarry Smith   PetscErrorCode   ierr;
213724c2c99SHong Zhang   PC_CompositeLink next = jac->head,next_tmp;
2144b9ad928SBarry Smith 
2154b9ad928SBarry Smith   PetscFunctionBegin;
21669d2c0f9SBarry Smith   ierr = PCReset_Composite(pc);CHKERRQ(ierr);
2174b9ad928SBarry Smith   while (next) {
2186bf464f9SBarry Smith     ierr     = PCDestroy(&next->pc);CHKERRQ(ierr);
219724c2c99SHong Zhang     next_tmp = next;
2204b9ad928SBarry Smith     next     = next->next;
221724c2c99SHong Zhang     ierr     = PetscFree(next_tmp);CHKERRQ(ierr);
2224b9ad928SBarry Smith   }
223c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2244b9ad928SBarry Smith   PetscFunctionReturn(0);
2254b9ad928SBarry Smith }
2264b9ad928SBarry Smith 
2274416b707SBarry Smith static PetscErrorCode PCSetFromOptions_Composite(PetscOptionItems *PetscOptionsObject,PC pc)
2284b9ad928SBarry Smith {
2294b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
230dfbe8321SBarry Smith   PetscErrorCode   ierr;
2319dcbbd2bSBarry Smith   PetscInt         nmax = 8,i;
2324b9ad928SBarry Smith   PC_CompositeLink next;
233e5999256SBarry Smith   char             *pcs[8];
234ace3abfcSBarry Smith   PetscBool        flg;
2354b9ad928SBarry Smith 
2364b9ad928SBarry Smith   PetscFunctionBegin;
237e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Composite preconditioner options");CHKERRQ(ierr);
2389dcbbd2bSBarry Smith   ierr = PetscOptionsEnum("-pc_composite_type","Type of composition","PCCompositeSetType",PCCompositeTypes,(PetscEnum)jac->type,(PetscEnum*)&jac->type,&flg);CHKERRQ(ierr);
23951f519a2SBarry Smith   if (flg) {
24051f519a2SBarry Smith     ierr = PCCompositeSetType(pc,jac->type);CHKERRQ(ierr);
24151f519a2SBarry Smith   }
2428aa07aa6SMatthew G. Knepley   ierr = PetscOptionsStringArray("-pc_composite_pcs","List of composite solvers","PCCompositeAddPCType",pcs,&nmax,&flg);CHKERRQ(ierr);
2434b9ad928SBarry Smith   if (flg) {
2444b9ad928SBarry Smith     for (i=0; i<nmax; i++) {
2458aa07aa6SMatthew G. Knepley       ierr = PCCompositeAddPCType(pc,pcs[i]);CHKERRQ(ierr);
246724c2c99SHong Zhang       ierr = PetscFree(pcs[i]);CHKERRQ(ierr);   /* deallocate string pcs[i], which is allocated in PetscOptionsStringArray() */
2474b9ad928SBarry Smith     }
2484b9ad928SBarry Smith   }
2494b9ad928SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2504b9ad928SBarry Smith 
2514b9ad928SBarry Smith   next = jac->head;
2524b9ad928SBarry Smith   while (next) {
2534b9ad928SBarry Smith     ierr = PCSetFromOptions(next->pc);CHKERRQ(ierr);
2544b9ad928SBarry Smith     next = next->next;
2554b9ad928SBarry Smith   }
2564b9ad928SBarry Smith   PetscFunctionReturn(0);
2574b9ad928SBarry Smith }
2584b9ad928SBarry Smith 
2596849ba73SBarry Smith static PetscErrorCode PCView_Composite(PC pc,PetscViewer viewer)
2604b9ad928SBarry Smith {
2614b9ad928SBarry Smith   PC_Composite     *jac = (PC_Composite*)pc->data;
262dfbe8321SBarry Smith   PetscErrorCode   ierr;
2634b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
264ace3abfcSBarry Smith   PetscBool        iascii;
2654b9ad928SBarry Smith 
2664b9ad928SBarry Smith   PetscFunctionBegin;
267251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
26832077d6dSBarry Smith   if (iascii) {
2699dcbbd2bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Composite PC type - %s\n",PCCompositeTypes[jac->type]);CHKERRQ(ierr);
2704b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"PCs on composite preconditioner follow\n");CHKERRQ(ierr);
2714b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr);
2724b9ad928SBarry Smith   }
27332077d6dSBarry Smith   if (iascii) {
2744b9ad928SBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2754b9ad928SBarry Smith   }
2764b9ad928SBarry Smith   while (next) {
2774b9ad928SBarry Smith     ierr = PCView(next->pc,viewer);CHKERRQ(ierr);
2784b9ad928SBarry Smith     next = next->next;
2794b9ad928SBarry Smith   }
28032077d6dSBarry Smith   if (iascii) {
2814b9ad928SBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2824b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr);
2834b9ad928SBarry Smith   }
2844b9ad928SBarry Smith   PetscFunctionReturn(0);
2854b9ad928SBarry Smith }
2864b9ad928SBarry Smith 
2874b9ad928SBarry Smith /* ------------------------------------------------------------------------------*/
2884b9ad928SBarry Smith 
2891e6b0712SBarry Smith static PetscErrorCode  PCCompositeSpecialSetAlpha_Composite(PC pc,PetscScalar alpha)
2904b9ad928SBarry Smith {
2914b9ad928SBarry Smith   PC_Composite *jac = (PC_Composite*)pc->data;
2925fd66863SKarl Rupp 
2934b9ad928SBarry Smith   PetscFunctionBegin;
2944b9ad928SBarry Smith   jac->alpha = alpha;
2954b9ad928SBarry Smith   PetscFunctionReturn(0);
2964b9ad928SBarry Smith }
2974b9ad928SBarry Smith 
2981e6b0712SBarry Smith static PetscErrorCode  PCCompositeSetType_Composite(PC pc,PCCompositeType type)
2994b9ad928SBarry Smith {
300fad69fbaSJed Brown   PC_Composite *jac = (PC_Composite*)pc->data;
301fad69fbaSJed Brown 
3024b9ad928SBarry Smith   PetscFunctionBegin;
3034b9ad928SBarry Smith   if (type == PC_COMPOSITE_ADDITIVE) {
3044b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Additive;
3052533e041SBarry Smith     pc->ops->applytranspose = PCApplyTranspose_Composite_Additive;
306421e10b8SBarry Smith   } else if (type ==  PC_COMPOSITE_MULTIPLICATIVE || type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
3074b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Multiplicative;
3082533e041SBarry Smith     pc->ops->applytranspose = PCApplyTranspose_Composite_Multiplicative;
3094b9ad928SBarry Smith   } else if (type ==  PC_COMPOSITE_SPECIAL) {
3104b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Special;
3110298fd71SBarry Smith     pc->ops->applytranspose = NULL;
312a7261c6bSprj-   } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown composite preconditioner type");
313fad69fbaSJed Brown   jac->type = type;
3144b9ad928SBarry Smith   PetscFunctionReturn(0);
3154b9ad928SBarry Smith }
3164b9ad928SBarry Smith 
317c60c7ad4SBarry Smith static PetscErrorCode  PCCompositeGetType_Composite(PC pc,PCCompositeType *type)
318c60c7ad4SBarry Smith {
319c60c7ad4SBarry Smith   PC_Composite *jac = (PC_Composite*)pc->data;
320c60c7ad4SBarry Smith 
321c60c7ad4SBarry Smith   PetscFunctionBegin;
322c60c7ad4SBarry Smith   *type = jac->type;
323c60c7ad4SBarry Smith   PetscFunctionReturn(0);
324c60c7ad4SBarry Smith }
325c60c7ad4SBarry Smith 
3268aa07aa6SMatthew G. Knepley static PetscErrorCode PCCompositeAddPC_Composite(PC pc, PC subpc)
3274b9ad928SBarry Smith {
3284b9ad928SBarry Smith   PC_Composite    *jac;
3295a9f2f41SSatish Balay   PC_CompositeLink next, ilink;
33079416396SBarry Smith   PetscInt         cnt = 0;
3312dcb1b2aSMatthew Knepley   const char      *prefix;
332d726e3a5SJed Brown   char             newprefix[20];
3338aa07aa6SMatthew G. Knepley   PetscErrorCode   ierr;
3344b9ad928SBarry Smith 
3354b9ad928SBarry Smith   PetscFunctionBegin;
336b00a9115SJed Brown   ierr = PetscNewLog(pc, &ilink);CHKERRQ(ierr);
3370a545947SLisandro Dalcin   ilink->next = NULL;
3388aa07aa6SMatthew G. Knepley   ilink->pc   = subpc;
3394b9ad928SBarry Smith 
3404b9ad928SBarry Smith   jac  = (PC_Composite *) pc->data;
3414b9ad928SBarry Smith   next = jac->head;
3424b9ad928SBarry Smith   if (!next) {
3435a9f2f41SSatish Balay     jac->head       = ilink;
3440298fd71SBarry Smith     ilink->previous = NULL;
3454b9ad928SBarry Smith   } else {
3464b9ad928SBarry Smith     cnt++;
3474b9ad928SBarry Smith     while (next->next) {
3484b9ad928SBarry Smith       next = next->next;
3494b9ad928SBarry Smith       cnt++;
3504b9ad928SBarry Smith     }
3515a9f2f41SSatish Balay     next->next      = ilink;
352421e10b8SBarry Smith     ilink->previous = next;
3534b9ad928SBarry Smith   }
3544b9ad928SBarry Smith   ierr = PCGetOptionsPrefix(pc, &prefix);CHKERRQ(ierr);
3558aa07aa6SMatthew G. Knepley   ierr = PCSetOptionsPrefix(subpc, prefix);CHKERRQ(ierr);
3568aa07aa6SMatthew G. Knepley   ierr = PetscSNPrintf(newprefix, 20, "sub_%d_", (int) cnt);CHKERRQ(ierr);
3578aa07aa6SMatthew G. Knepley   ierr = PCAppendOptionsPrefix(subpc, newprefix);CHKERRQ(ierr);
3588aa07aa6SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) subpc);CHKERRQ(ierr);
3598aa07aa6SMatthew G. Knepley   PetscFunctionReturn(0);
3608aa07aa6SMatthew G. Knepley }
3618aa07aa6SMatthew G. Knepley 
3628aa07aa6SMatthew G. Knepley static PetscErrorCode PCCompositeAddPCType_Composite(PC pc, PCType type)
3638aa07aa6SMatthew G. Knepley {
3648aa07aa6SMatthew G. Knepley   PC             subpc;
3658aa07aa6SMatthew G. Knepley   PetscErrorCode ierr;
3668aa07aa6SMatthew G. Knepley 
3678aa07aa6SMatthew G. Knepley   PetscFunctionBegin;
3688aa07aa6SMatthew G. Knepley   ierr = PCCreate(PetscObjectComm((PetscObject)pc), &subpc);CHKERRQ(ierr);
3698aa07aa6SMatthew G. Knepley   ierr = PetscObjectIncrementTabLevel((PetscObject) subpc, (PetscObject) pc, 1);CHKERRQ(ierr);
3708aa07aa6SMatthew G. Knepley   ierr = PetscLogObjectParent((PetscObject) pc, (PetscObject) subpc);CHKERRQ(ierr);
3718aa07aa6SMatthew G. Knepley   ierr = PCCompositeAddPC_Composite(pc, subpc);CHKERRQ(ierr);
3724b9ad928SBarry Smith   /* type is set after prefix, because some methods may modify prefix, e.g. pcksp */
3738aa07aa6SMatthew G. Knepley   ierr = PCSetType(subpc, type);CHKERRQ(ierr);
3748aa07aa6SMatthew G. Knepley   ierr = PCDestroy(&subpc);CHKERRQ(ierr);
3754b9ad928SBarry Smith   PetscFunctionReturn(0);
3764b9ad928SBarry Smith }
3774b9ad928SBarry Smith 
3788e6eba06SBarry Smith static PetscErrorCode  PCCompositeGetNumberPC_Composite(PC pc,PetscInt *n)
3798e6eba06SBarry Smith {
3808e6eba06SBarry Smith   PC_Composite     *jac;
3818e6eba06SBarry Smith   PC_CompositeLink next;
3828e6eba06SBarry Smith 
3838e6eba06SBarry Smith   PetscFunctionBegin;
3848e6eba06SBarry Smith   jac  = (PC_Composite*)pc->data;
3858e6eba06SBarry Smith   next = jac->head;
3868e6eba06SBarry Smith   *n = 0;
3878e6eba06SBarry Smith   while (next) {
3888e6eba06SBarry Smith     next = next->next;
3898e6eba06SBarry Smith     (*n) ++;
3908e6eba06SBarry Smith   }
3918e6eba06SBarry Smith   PetscFunctionReturn(0);
3928e6eba06SBarry Smith }
3938e6eba06SBarry Smith 
3941e6b0712SBarry Smith static PetscErrorCode  PCCompositeGetPC_Composite(PC pc,PetscInt n,PC *subpc)
3954b9ad928SBarry Smith {
3964b9ad928SBarry Smith   PC_Composite     *jac;
3974b9ad928SBarry Smith   PC_CompositeLink next;
39879416396SBarry Smith   PetscInt         i;
3994b9ad928SBarry Smith 
4004b9ad928SBarry Smith   PetscFunctionBegin;
4014b9ad928SBarry Smith   jac  = (PC_Composite*)pc->data;
4024b9ad928SBarry Smith   next = jac->head;
4034b9ad928SBarry Smith   for (i=0; i<n; i++) {
404*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!next->next,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Not enough PCs in composite preconditioner");
4054b9ad928SBarry Smith     next = next->next;
4064b9ad928SBarry Smith   }
4074b9ad928SBarry Smith   *subpc = next->pc;
4084b9ad928SBarry Smith   PetscFunctionReturn(0);
4094b9ad928SBarry Smith }
4104b9ad928SBarry Smith 
4114b9ad928SBarry Smith /* -------------------------------------------------------------------------------- */
412f39d8e23SSatish Balay /*@
4134b9ad928SBarry Smith    PCCompositeSetType - Sets the type of composite preconditioner.
4144b9ad928SBarry Smith 
415ad4df100SBarry Smith    Logically Collective on PC
4164b9ad928SBarry Smith 
417c60c7ad4SBarry Smith    Input Parameters:
4182a6744ebSBarry Smith +  pc - the preconditioner context
4192a6744ebSBarry Smith -  type - PC_COMPOSITE_ADDITIVE (default), PC_COMPOSITE_MULTIPLICATIVE, PC_COMPOSITE_SPECIAL
4204b9ad928SBarry Smith 
4214b9ad928SBarry Smith    Options Database Key:
4224b9ad928SBarry Smith .  -pc_composite_type <type: one of multiplicative, additive, special> - Sets composite preconditioner type
4234b9ad928SBarry Smith 
4244b9ad928SBarry Smith    Level: Developer
4254b9ad928SBarry Smith 
4264b9ad928SBarry Smith @*/
4277087cfbeSBarry Smith PetscErrorCode  PCCompositeSetType(PC pc,PCCompositeType type)
4284b9ad928SBarry Smith {
4297bb14e67SBarry Smith   PetscErrorCode ierr;
4304b9ad928SBarry Smith 
4314b9ad928SBarry Smith   PetscFunctionBegin;
4320700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
433c5eb9154SBarry Smith   PetscValidLogicalCollectiveEnum(pc,type,2);
4347bb14e67SBarry Smith   ierr = PetscTryMethod(pc,"PCCompositeSetType_C",(PC,PCCompositeType),(pc,type));CHKERRQ(ierr);
4354b9ad928SBarry Smith   PetscFunctionReturn(0);
4364b9ad928SBarry Smith }
4374b9ad928SBarry Smith 
438c60c7ad4SBarry Smith /*@
439721f67b5SBarry Smith    PCCompositeGetType - Gets the type of composite preconditioner.
440c60c7ad4SBarry Smith 
441c60c7ad4SBarry Smith    Logically Collective on PC
442c60c7ad4SBarry Smith 
443c60c7ad4SBarry Smith    Input Parameter:
444c60c7ad4SBarry Smith .  pc - the preconditioner context
445c60c7ad4SBarry Smith 
446c60c7ad4SBarry Smith    Output Parameter:
447c60c7ad4SBarry Smith .  type - PC_COMPOSITE_ADDITIVE (default), PC_COMPOSITE_MULTIPLICATIVE, PC_COMPOSITE_SPECIAL
448c60c7ad4SBarry Smith 
449c60c7ad4SBarry Smith    Options Database Key:
450c60c7ad4SBarry Smith .  -pc_composite_type <type: one of multiplicative, additive, special> - Sets composite preconditioner type
451c60c7ad4SBarry Smith 
452c60c7ad4SBarry Smith    Level: Developer
453c60c7ad4SBarry Smith 
454c60c7ad4SBarry Smith @*/
455c60c7ad4SBarry Smith PetscErrorCode  PCCompositeGetType(PC pc,PCCompositeType *type)
456c60c7ad4SBarry Smith {
457c60c7ad4SBarry Smith   PetscErrorCode ierr;
458c60c7ad4SBarry Smith 
459c60c7ad4SBarry Smith   PetscFunctionBegin;
460c60c7ad4SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
461c60c7ad4SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetType_C",(PC,PCCompositeType*),(pc,type));CHKERRQ(ierr);
462c60c7ad4SBarry Smith   PetscFunctionReturn(0);
463c60c7ad4SBarry Smith }
464c60c7ad4SBarry Smith 
465f39d8e23SSatish Balay /*@
4664b9ad928SBarry Smith    PCCompositeSpecialSetAlpha - Sets alpha for the special composite preconditioner
4674b9ad928SBarry Smith      for alphaI + R + S
4684b9ad928SBarry Smith 
469ad4df100SBarry Smith    Logically Collective on PC
4704b9ad928SBarry Smith 
471d8d19677SJose E. Roman    Input Parameters:
4724b9ad928SBarry Smith +  pc - the preconditioner context
4734b9ad928SBarry Smith -  alpha - scale on identity
4744b9ad928SBarry Smith 
4754b9ad928SBarry Smith    Level: Developer
4764b9ad928SBarry Smith 
4774b9ad928SBarry Smith @*/
4787087cfbeSBarry Smith PetscErrorCode  PCCompositeSpecialSetAlpha(PC pc,PetscScalar alpha)
4794b9ad928SBarry Smith {
4804ac538c5SBarry Smith   PetscErrorCode ierr;
4814b9ad928SBarry Smith 
4824b9ad928SBarry Smith   PetscFunctionBegin;
4830700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
484c5eb9154SBarry Smith   PetscValidLogicalCollectiveScalar(pc,alpha,2);
4854ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCCompositeSpecialSetAlpha_C",(PC,PetscScalar),(pc,alpha));CHKERRQ(ierr);
4864b9ad928SBarry Smith   PetscFunctionReturn(0);
4874b9ad928SBarry Smith }
4884b9ad928SBarry Smith 
4894b9ad928SBarry Smith /*@C
4908aa07aa6SMatthew G. Knepley   PCCompositeAddPCType - Adds another PC of the given type to the composite PC.
4914b9ad928SBarry Smith 
4924b9ad928SBarry Smith   Collective on PC
4934b9ad928SBarry Smith 
4944b9ad928SBarry Smith   Input Parameters:
4952a6744ebSBarry Smith + pc - the preconditioner context
4962a6744ebSBarry Smith - type - the type of the new preconditioner
4974b9ad928SBarry Smith 
4984b9ad928SBarry Smith   Level: Developer
4994b9ad928SBarry Smith 
5008aa07aa6SMatthew G. Knepley .seealso: PCCompositeAddPC()
5014b9ad928SBarry Smith @*/
5028aa07aa6SMatthew G. Knepley PetscErrorCode  PCCompositeAddPCType(PC pc,PCType type)
5034b9ad928SBarry Smith {
5044ac538c5SBarry Smith   PetscErrorCode ierr;
5054b9ad928SBarry Smith 
5064b9ad928SBarry Smith   PetscFunctionBegin;
5070700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5088aa07aa6SMatthew G. Knepley   ierr = PetscTryMethod(pc,"PCCompositeAddPCType_C",(PC,PCType),(pc,type));CHKERRQ(ierr);
5098aa07aa6SMatthew G. Knepley   PetscFunctionReturn(0);
5108aa07aa6SMatthew G. Knepley }
5118aa07aa6SMatthew G. Knepley 
5128aa07aa6SMatthew G. Knepley /*@
5138aa07aa6SMatthew G. Knepley   PCCompositeAddPC - Adds another PC to the composite PC.
5148aa07aa6SMatthew G. Knepley 
5158aa07aa6SMatthew G. Knepley   Collective on PC
5168aa07aa6SMatthew G. Knepley 
5178aa07aa6SMatthew G. Knepley   Input Parameters:
5188aa07aa6SMatthew G. Knepley + pc    - the preconditioner context
5198aa07aa6SMatthew G. Knepley - subpc - the new preconditioner
5208aa07aa6SMatthew G. Knepley 
5218aa07aa6SMatthew G. Knepley    Level: Developer
5228aa07aa6SMatthew G. Knepley 
5238aa07aa6SMatthew G. Knepley .seealso: PCCompositeAddPCType()
5248aa07aa6SMatthew G. Knepley @*/
5258aa07aa6SMatthew G. Knepley PetscErrorCode PCCompositeAddPC(PC pc, PC subpc)
5268aa07aa6SMatthew G. Knepley {
5278aa07aa6SMatthew G. Knepley   PetscErrorCode ierr;
5288aa07aa6SMatthew G. Knepley 
5298aa07aa6SMatthew G. Knepley   PetscFunctionBegin;
5308aa07aa6SMatthew G. Knepley   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5318aa07aa6SMatthew G. Knepley   PetscValidHeaderSpecific(subpc,PC_CLASSID,2);
5328aa07aa6SMatthew G. Knepley   ierr = PetscTryMethod(pc,"PCCompositeAddPC_C",(PC,PC),(pc,subpc));CHKERRQ(ierr);
5334b9ad928SBarry Smith   PetscFunctionReturn(0);
5344b9ad928SBarry Smith }
5354b9ad928SBarry Smith 
5368e6eba06SBarry Smith /*@
5378e6eba06SBarry Smith    PCCompositeGetNumberPC - Gets the number of PC objects in the composite PC.
5388e6eba06SBarry Smith 
5398e6eba06SBarry Smith    Not Collective
5408e6eba06SBarry Smith 
5418e6eba06SBarry Smith    Input Parameter:
5428e6eba06SBarry Smith .  pc - the preconditioner context
5438e6eba06SBarry Smith 
5448e6eba06SBarry Smith    Output Parameter:
5458e6eba06SBarry Smith .  num - the number of sub pcs
5468e6eba06SBarry Smith 
5478e6eba06SBarry Smith    Level: Developer
5488e6eba06SBarry Smith 
5498e6eba06SBarry Smith .seealso: PCCompositeGetPC()
5508e6eba06SBarry Smith @*/
5518e6eba06SBarry Smith PetscErrorCode  PCCompositeGetNumberPC(PC pc,PetscInt *num)
5528e6eba06SBarry Smith {
5538e6eba06SBarry Smith   PetscErrorCode ierr;
5548e6eba06SBarry Smith 
5558e6eba06SBarry Smith   PetscFunctionBegin;
5568e6eba06SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5578e6eba06SBarry Smith   PetscValidIntPointer(num,2);
5588e6eba06SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetNumberPC_C",(PC,PetscInt*),(pc,num));CHKERRQ(ierr);
5598e6eba06SBarry Smith   PetscFunctionReturn(0);
5608e6eba06SBarry Smith }
5618e6eba06SBarry Smith 
562f39d8e23SSatish Balay /*@
5634b9ad928SBarry Smith    PCCompositeGetPC - Gets one of the PC objects in the composite PC.
5644b9ad928SBarry Smith 
5654b9ad928SBarry Smith    Not Collective
5664b9ad928SBarry Smith 
567d8d19677SJose E. Roman    Input Parameters:
5682a6744ebSBarry Smith +  pc - the preconditioner context
5692a6744ebSBarry Smith -  n - the number of the pc requested
5704b9ad928SBarry Smith 
5714b9ad928SBarry Smith    Output Parameters:
5724b9ad928SBarry Smith .  subpc - the PC requested
5734b9ad928SBarry Smith 
5744b9ad928SBarry Smith    Level: Developer
5754b9ad928SBarry Smith 
57695452b02SPatrick Sanan     Notes:
57795452b02SPatrick Sanan     To use a different operator to construct one of the inner preconditioners first call PCCompositeGetPC(), then
5782b1d202aSBarry Smith             call PCSetOperators() on that PC.
5792b1d202aSBarry Smith 
5808aa07aa6SMatthew G. Knepley .seealso: PCCompositeAddPCType(), PCCompositeGetNumberPC(), PCSetOperators()
5814b9ad928SBarry Smith @*/
5827087cfbeSBarry Smith PetscErrorCode PCCompositeGetPC(PC pc,PetscInt n,PC *subpc)
5834b9ad928SBarry Smith {
5844ac538c5SBarry Smith   PetscErrorCode ierr;
5854b9ad928SBarry Smith 
5864b9ad928SBarry Smith   PetscFunctionBegin;
5870700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5884482741eSBarry Smith   PetscValidPointer(subpc,3);
5894ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCCompositeGetPC_C",(PC,PetscInt,PC*),(pc,n,subpc));CHKERRQ(ierr);
5904b9ad928SBarry Smith   PetscFunctionReturn(0);
5914b9ad928SBarry Smith }
5924b9ad928SBarry Smith 
5934b9ad928SBarry Smith /* -------------------------------------------------------------------------------------------*/
5944b9ad928SBarry Smith 
5954b9ad928SBarry Smith /*MC
5964b9ad928SBarry Smith      PCCOMPOSITE - Build a preconditioner by composing together several preconditioners
5974b9ad928SBarry Smith 
5984b9ad928SBarry Smith    Options Database Keys:
5992eab2d5bSJungho Lee +  -pc_composite_type <type: one of multiplicative, additive, symmetric_multiplicative, special> - Sets composite preconditioner type
6002b1d202aSBarry Smith .  -pc_use_amat - activates PCSetUseAmat()
60151f519a2SBarry Smith -  -pc_composite_pcs - <pc0,pc1,...> list of PCs to compose
6024b9ad928SBarry Smith 
6034b9ad928SBarry Smith    Level: intermediate
6044b9ad928SBarry Smith 
60595452b02SPatrick Sanan    Notes:
60695452b02SPatrick Sanan     To use a Krylov method inside the composite preconditioner, set the PCType of one or more
6074b9ad928SBarry Smith           inner PCs to be PCKSP.
6084b9ad928SBarry Smith           Using a Krylov method inside another Krylov method can be dangerous (you get divergence or
609b3ef52cdSBarry Smith           the incorrect answer) unless you use KSPFGMRES as the outer Krylov method
6102b1d202aSBarry Smith           To use a different operator to construct one of the inner preconditioners first call PCCompositeGetPC(), then
6112b1d202aSBarry Smith           call PCSetOperators() on that PC.
6124b9ad928SBarry Smith 
6134b9ad928SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
6148aa07aa6SMatthew G. Knepley            PCSHELL, PCKSP, PCCompositeSetType(), PCCompositeSpecialSetAlpha(), PCCompositeAddPCType(),
61549517cdeSBarry Smith            PCCompositeGetPC(), PCSetUseAmat()
6164b9ad928SBarry Smith 
6174b9ad928SBarry Smith M*/
6184b9ad928SBarry Smith 
6198cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Composite(PC pc)
6204b9ad928SBarry Smith {
621dfbe8321SBarry Smith   PetscErrorCode ierr;
6224b9ad928SBarry Smith   PC_Composite   *jac;
6234b9ad928SBarry Smith 
6244b9ad928SBarry Smith   PetscFunctionBegin;
625b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
6262fa5cd67SKarl Rupp 
6274b9ad928SBarry Smith   pc->ops->apply           = PCApply_Composite_Additive;
6282533e041SBarry Smith   pc->ops->applytranspose  = PCApplyTranspose_Composite_Additive;
6294b9ad928SBarry Smith   pc->ops->setup           = PCSetUp_Composite;
63069d2c0f9SBarry Smith   pc->ops->reset           = PCReset_Composite;
6314b9ad928SBarry Smith   pc->ops->destroy         = PCDestroy_Composite;
6324b9ad928SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Composite;
6334b9ad928SBarry Smith   pc->ops->view            = PCView_Composite;
6340a545947SLisandro Dalcin   pc->ops->applyrichardson = NULL;
6354b9ad928SBarry Smith 
6364b9ad928SBarry Smith   pc->data   = (void*)jac;
6374b9ad928SBarry Smith   jac->type  = PC_COMPOSITE_ADDITIVE;
6380a545947SLisandro Dalcin   jac->work1 = NULL;
6390a545947SLisandro Dalcin   jac->work2 = NULL;
6400a545947SLisandro Dalcin   jac->head  = NULL;
6414b9ad928SBarry Smith 
642bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeSetType_C",PCCompositeSetType_Composite);CHKERRQ(ierr);
643c60c7ad4SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetType_C",PCCompositeGetType_Composite);CHKERRQ(ierr);
6448aa07aa6SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeAddPCType_C",PCCompositeAddPCType_Composite);CHKERRQ(ierr);
645bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeAddPC_C",PCCompositeAddPC_Composite);CHKERRQ(ierr);
6468e6eba06SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetNumberPC_C",PCCompositeGetNumberPC_Composite);CHKERRQ(ierr);
647bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetPC_C",PCCompositeGetPC_Composite);CHKERRQ(ierr);
648bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeSpecialSetAlpha_C",PCCompositeSpecialSetAlpha_Composite);CHKERRQ(ierr);
6494b9ad928SBarry Smith   PetscFunctionReturn(0);
6504b9ad928SBarry Smith }
651