xref: /petsc/src/ksp/pc/impls/composite/composite.c (revision fe972ab94a72e07fc8dae81dd2ded1f8f457b5bc)
14b9ad928SBarry Smith /*
24b9ad928SBarry Smith       Defines a preconditioner that can consist of a collection of PCs
34b9ad928SBarry Smith */
4af0996ceSBarry Smith #include <petsc/private/pcimpl.h>
5c6db04a5SJed Brown #include <petscksp.h> /*I "petscksp.h" I*/
64b9ad928SBarry Smith 
74b9ad928SBarry Smith typedef struct _PC_CompositeLink *PC_CompositeLink;
84b9ad928SBarry Smith struct _PC_CompositeLink {
94b9ad928SBarry Smith   PC               pc;
104b9ad928SBarry Smith   PC_CompositeLink next;
11421e10b8SBarry Smith   PC_CompositeLink previous;
124b9ad928SBarry Smith };
134b9ad928SBarry Smith 
144b9ad928SBarry Smith typedef struct {
154b9ad928SBarry Smith   PC_CompositeLink head;
164b9ad928SBarry Smith   PCCompositeType  type;
174b9ad928SBarry Smith   Vec              work1;
184b9ad928SBarry Smith   Vec              work2;
194b9ad928SBarry Smith   PetscScalar      alpha;
204b9ad928SBarry Smith } PC_Composite;
214b9ad928SBarry Smith 
22d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_Composite_Multiplicative(PC pc, Vec x, Vec y)
23d71ae5a4SJacob Faibussowitsch {
244b9ad928SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
254b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
264b9ad928SBarry Smith   Mat              mat  = pc->pmat;
274b9ad928SBarry Smith 
284b9ad928SBarry Smith   PetscFunctionBegin;
2928b400f6SJacob Faibussowitsch   PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
30450d59ebSPatrick Farrell 
31450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
32450d59ebSPatrick Farrell   while (next) {
339566063dSJacob Faibussowitsch     PetscCall(PCSetReusePreconditioner(next->pc, pc->reusepreconditioner));
34450d59ebSPatrick Farrell     next = next->next;
35450d59ebSPatrick Farrell   }
36450d59ebSPatrick Farrell   next = jac->head;
37450d59ebSPatrick Farrell 
384b9ad928SBarry Smith   if (next->next && !jac->work2) { /* allocate second work vector */
399566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(jac->work1, &jac->work2));
404b9ad928SBarry Smith   }
4149517cdeSBarry Smith   if (pc->useAmat) mat = pc->mat;
429566063dSJacob Faibussowitsch   PetscCall(PCApply(next->pc, x, y)); /* y <- B x */
434b9ad928SBarry Smith   while (next->next) {
444b9ad928SBarry Smith     next = next->next;
459566063dSJacob Faibussowitsch     PetscCall(MatMult(mat, y, jac->work1));               /* work1 <- A y */
469566063dSJacob Faibussowitsch     PetscCall(VecWAXPY(jac->work2, -1.0, jac->work1, x)); /* work2 <- x - work1 */
479566063dSJacob Faibussowitsch     PetscCall(PCApply(next->pc, jac->work2, jac->work1)); /* work1 <- C work2 */
489566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y, 1.0, jac->work1));               /* y <- y + work1 = B x + C (x - A B x) = (B + C (1 - A B)) x */
494b9ad928SBarry Smith   }
50421e10b8SBarry Smith   if (jac->type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
51421e10b8SBarry Smith     while (next->previous) {
52421e10b8SBarry Smith       next = next->previous;
539566063dSJacob Faibussowitsch       PetscCall(MatMult(mat, y, jac->work1));
549566063dSJacob Faibussowitsch       PetscCall(VecWAXPY(jac->work2, -1.0, jac->work1, x));
559566063dSJacob Faibussowitsch       PetscCall(PCApply(next->pc, jac->work2, jac->work1));
569566063dSJacob Faibussowitsch       PetscCall(VecAXPY(y, 1.0, jac->work1));
57421e10b8SBarry Smith     }
58421e10b8SBarry Smith   }
593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
604b9ad928SBarry Smith }
614b9ad928SBarry Smith 
62d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_Composite_Multiplicative(PC pc, Vec x, Vec y)
63d71ae5a4SJacob Faibussowitsch {
642533e041SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
652533e041SBarry Smith   PC_CompositeLink next = jac->head;
662533e041SBarry Smith   Mat              mat  = pc->pmat;
672533e041SBarry Smith 
682533e041SBarry Smith   PetscFunctionBegin;
6928b400f6SJacob Faibussowitsch   PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
702533e041SBarry Smith   if (next->next && !jac->work2) { /* allocate second work vector */
719566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(jac->work1, &jac->work2));
722533e041SBarry Smith   }
7349517cdeSBarry Smith   if (pc->useAmat) mat = pc->mat;
742533e041SBarry Smith   /* locate last PC */
75ad540459SPierre Jolivet   while (next->next) next = next->next;
769566063dSJacob Faibussowitsch   PetscCall(PCApplyTranspose(next->pc, x, y));
772533e041SBarry Smith   while (next->previous) {
782533e041SBarry Smith     next = next->previous;
799566063dSJacob Faibussowitsch     PetscCall(MatMultTranspose(mat, y, jac->work1));
809566063dSJacob Faibussowitsch     PetscCall(VecWAXPY(jac->work2, -1.0, jac->work1, x));
819566063dSJacob Faibussowitsch     PetscCall(PCApplyTranspose(next->pc, jac->work2, jac->work1));
829566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y, 1.0, jac->work1));
832533e041SBarry Smith   }
842533e041SBarry Smith   if (jac->type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
852533e041SBarry Smith     next = jac->head;
862533e041SBarry Smith     while (next->next) {
872533e041SBarry Smith       next = next->next;
889566063dSJacob Faibussowitsch       PetscCall(MatMultTranspose(mat, y, jac->work1));
899566063dSJacob Faibussowitsch       PetscCall(VecWAXPY(jac->work2, -1.0, jac->work1, x));
909566063dSJacob Faibussowitsch       PetscCall(PCApplyTranspose(next->pc, jac->work2, jac->work1));
919566063dSJacob Faibussowitsch       PetscCall(VecAXPY(y, 1.0, jac->work1));
922533e041SBarry Smith     }
932533e041SBarry Smith   }
943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
952533e041SBarry Smith }
962533e041SBarry Smith 
974b9ad928SBarry Smith /*
984b9ad928SBarry Smith     This is very special for a matrix of the form alpha I + R + S
994b9ad928SBarry Smith     where first preconditioner is built from alpha I + S and second from
1004b9ad928SBarry Smith     alpha I + R
1014b9ad928SBarry Smith */
102d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_Composite_Special(PC pc, Vec x, Vec y)
103d71ae5a4SJacob Faibussowitsch {
1044b9ad928SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
1054b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1064b9ad928SBarry Smith 
1074b9ad928SBarry Smith   PetscFunctionBegin;
10828b400f6SJacob Faibussowitsch   PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
1097827d75bSBarry Smith   PetscCheck(next->next && !next->next->next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Special composite preconditioners requires exactly two PCs");
1104b9ad928SBarry Smith 
111450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
1129566063dSJacob Faibussowitsch   PetscCall(PCSetReusePreconditioner(next->pc, pc->reusepreconditioner));
1139566063dSJacob Faibussowitsch   PetscCall(PCSetReusePreconditioner(next->next->pc, pc->reusepreconditioner));
114450d59ebSPatrick Farrell 
1159566063dSJacob Faibussowitsch   PetscCall(PCApply(next->pc, x, jac->work1));
1169566063dSJacob Faibussowitsch   PetscCall(PCApply(next->next->pc, jac->work1, y));
1173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1184b9ad928SBarry Smith }
1194b9ad928SBarry Smith 
120d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_Composite_Additive(PC pc, Vec x, Vec y)
121d71ae5a4SJacob Faibussowitsch {
1224b9ad928SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
1234b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1244b9ad928SBarry Smith 
1254b9ad928SBarry Smith   PetscFunctionBegin;
12628b400f6SJacob Faibussowitsch   PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
127450d59ebSPatrick Farrell 
128450d59ebSPatrick Farrell   /* Set the reuse flag on children PCs */
129450d59ebSPatrick Farrell   while (next) {
1309566063dSJacob Faibussowitsch     PetscCall(PCSetReusePreconditioner(next->pc, pc->reusepreconditioner));
131450d59ebSPatrick Farrell     next = next->next;
132450d59ebSPatrick Farrell   }
133450d59ebSPatrick Farrell   next = jac->head;
134450d59ebSPatrick Farrell 
1359566063dSJacob Faibussowitsch   PetscCall(PCApply(next->pc, x, y));
1364b9ad928SBarry Smith   while (next->next) {
1374b9ad928SBarry Smith     next = next->next;
1389566063dSJacob Faibussowitsch     PetscCall(PCApply(next->pc, x, jac->work1));
1399566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y, 1.0, jac->work1));
1404b9ad928SBarry Smith   }
1413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1424b9ad928SBarry Smith }
1434b9ad928SBarry Smith 
144d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_Composite_Additive(PC pc, Vec x, Vec y)
145d71ae5a4SJacob Faibussowitsch {
1462533e041SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
1472533e041SBarry Smith   PC_CompositeLink next = jac->head;
1482533e041SBarry Smith 
1492533e041SBarry Smith   PetscFunctionBegin;
15028b400f6SJacob Faibussowitsch   PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs");
1519566063dSJacob Faibussowitsch   PetscCall(PCApplyTranspose(next->pc, x, y));
1522533e041SBarry Smith   while (next->next) {
1532533e041SBarry Smith     next = next->next;
1549566063dSJacob Faibussowitsch     PetscCall(PCApplyTranspose(next->pc, x, jac->work1));
1559566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y, 1.0, jac->work1));
1562533e041SBarry Smith   }
1573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1582533e041SBarry Smith }
1592533e041SBarry Smith 
160d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_Composite(PC pc)
161d71ae5a4SJacob Faibussowitsch {
1624b9ad928SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
1634b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
1645a78d018SMatthew G. Knepley   DM               dm;
1654b9ad928SBarry Smith 
1664b9ad928SBarry Smith   PetscFunctionBegin;
16748a46eb9SPierre Jolivet   if (!jac->work1) PetscCall(MatCreateVecs(pc->pmat, &jac->work1, NULL));
1689566063dSJacob Faibussowitsch   PetscCall(PCGetDM(pc, &dm));
1694b9ad928SBarry Smith   while (next) {
17048a46eb9SPierre Jolivet     if (!next->pc->dm) PetscCall(PCSetDM(next->pc, dm));
17148a46eb9SPierre Jolivet     if (!next->pc->mat) PetscCall(PCSetOperators(next->pc, pc->mat, pc->pmat));
1724b9ad928SBarry Smith     next = next->next;
1734b9ad928SBarry Smith   }
1743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1754b9ad928SBarry Smith }
1764b9ad928SBarry Smith 
1774f853519SStefano Zampini static PetscErrorCode PCSetUpOnBlocks_Composite(PC pc)
1784f853519SStefano Zampini {
1794f853519SStefano Zampini   PC_Composite    *jac  = (PC_Composite *)pc->data;
1804f853519SStefano Zampini   PC_CompositeLink next = jac->head;
1814f853519SStefano Zampini   PCFailedReason   reason;
1824f853519SStefano Zampini 
1834f853519SStefano Zampini   PetscFunctionBegin;
1844f853519SStefano Zampini   while (next) {
1854f853519SStefano Zampini     PetscCall(PCSetUp(next->pc));
1864f853519SStefano Zampini     PetscCall(PCGetFailedReasonRank(next->pc, &reason));
1874f853519SStefano Zampini     if (reason) pc->failedreason = reason;
1884f853519SStefano Zampini     next = next->next;
1894f853519SStefano Zampini   }
1904f853519SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
1914f853519SStefano Zampini }
1924f853519SStefano Zampini 
193d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_Composite(PC pc)
194d71ae5a4SJacob Faibussowitsch {
19569d2c0f9SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
1965f48b12bSBarry Smith   PC_CompositeLink next = jac->head;
19769d2c0f9SBarry Smith 
19869d2c0f9SBarry Smith   PetscFunctionBegin;
19969d2c0f9SBarry Smith   while (next) {
2009566063dSJacob Faibussowitsch     PetscCall(PCReset(next->pc));
20169d2c0f9SBarry Smith     next = next->next;
20269d2c0f9SBarry Smith   }
2039566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&jac->work1));
2049566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&jac->work2));
2053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20669d2c0f9SBarry Smith }
20769d2c0f9SBarry Smith 
208d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_Composite(PC pc)
209d71ae5a4SJacob Faibussowitsch {
2104b9ad928SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
211724c2c99SHong Zhang   PC_CompositeLink next = jac->head, next_tmp;
2124b9ad928SBarry Smith 
2134b9ad928SBarry Smith   PetscFunctionBegin;
2149566063dSJacob Faibussowitsch   PetscCall(PCReset_Composite(pc));
2154b9ad928SBarry Smith   while (next) {
2169566063dSJacob Faibussowitsch     PetscCall(PCDestroy(&next->pc));
217724c2c99SHong Zhang     next_tmp = next;
2184b9ad928SBarry Smith     next     = next->next;
2199566063dSJacob Faibussowitsch     PetscCall(PetscFree(next_tmp));
2204b9ad928SBarry Smith   }
2212e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSetType_C", NULL));
2222e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetType_C", NULL));
2232e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeAddPCType_C", NULL));
2242e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeAddPC_C", NULL));
2252e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetNumberPC_C", NULL));
2262e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetPC_C", NULL));
2272e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSpecialSetAlpha_C", NULL));
2289566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
2293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2304b9ad928SBarry Smith }
2314b9ad928SBarry Smith 
232d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_Composite(PC pc, PetscOptionItems *PetscOptionsObject)
233d71ae5a4SJacob Faibussowitsch {
2344b9ad928SBarry Smith   PC_Composite    *jac = (PC_Composite *)pc->data;
235*fe972ab9SMatthew G. Knepley   PetscInt         nmax, i;
2364b9ad928SBarry Smith   PC_CompositeLink next;
237*fe972ab9SMatthew G. Knepley   char            *pcs[1024];
238ace3abfcSBarry Smith   PetscBool        flg;
2394b9ad928SBarry Smith 
2404b9ad928SBarry Smith   PetscFunctionBegin;
241d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "Composite preconditioner options");
2429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-pc_composite_type", "Type of composition", "PCCompositeSetType", PCCompositeTypes, (PetscEnum)jac->type, (PetscEnum *)&jac->type, &flg));
2431baa6e33SBarry Smith   if (flg) PetscCall(PCCompositeSetType(pc, jac->type));
244*fe972ab9SMatthew G. Knepley   nmax = (PetscInt)PETSC_STATIC_ARRAY_LENGTH(pcs);
2459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringArray("-pc_composite_pcs", "List of composite solvers", "PCCompositeAddPCType", pcs, &nmax, &flg));
2464b9ad928SBarry Smith   if (flg) {
2474b9ad928SBarry Smith     for (i = 0; i < nmax; i++) {
2489566063dSJacob Faibussowitsch       PetscCall(PCCompositeAddPCType(pc, pcs[i]));
2499566063dSJacob Faibussowitsch       PetscCall(PetscFree(pcs[i])); /* deallocate string pcs[i], which is allocated in PetscOptionsStringArray() */
2504b9ad928SBarry Smith     }
2514b9ad928SBarry Smith   }
252d0609cedSBarry Smith   PetscOptionsHeadEnd();
2534b9ad928SBarry Smith 
2544b9ad928SBarry Smith   next = jac->head;
2554b9ad928SBarry Smith   while (next) {
2569566063dSJacob Faibussowitsch     PetscCall(PCSetFromOptions(next->pc));
2574b9ad928SBarry Smith     next = next->next;
2584b9ad928SBarry Smith   }
2593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2604b9ad928SBarry Smith }
2614b9ad928SBarry Smith 
262d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_Composite(PC pc, PetscViewer viewer)
263d71ae5a4SJacob Faibussowitsch {
2644b9ad928SBarry Smith   PC_Composite    *jac  = (PC_Composite *)pc->data;
2654b9ad928SBarry Smith   PC_CompositeLink next = jac->head;
266ace3abfcSBarry Smith   PetscBool        iascii;
2674b9ad928SBarry Smith 
2684b9ad928SBarry Smith   PetscFunctionBegin;
2699566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
27032077d6dSBarry Smith   if (iascii) {
2719566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Composite PC type - %s\n", PCCompositeTypes[jac->type]));
2729566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "PCs on composite preconditioner follow\n"));
2739566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "---------------------------------\n"));
2744b9ad928SBarry Smith   }
2751baa6e33SBarry Smith   if (iascii) PetscCall(PetscViewerASCIIPushTab(viewer));
2764b9ad928SBarry Smith   while (next) {
2779566063dSJacob Faibussowitsch     PetscCall(PCView(next->pc, viewer));
2784b9ad928SBarry Smith     next = next->next;
2794b9ad928SBarry Smith   }
28032077d6dSBarry Smith   if (iascii) {
2819566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
2829566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "---------------------------------\n"));
2834b9ad928SBarry Smith   }
2843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2854b9ad928SBarry Smith }
2864b9ad928SBarry Smith 
287d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeSpecialSetAlpha_Composite(PC pc, PetscScalar alpha)
288d71ae5a4SJacob Faibussowitsch {
2894b9ad928SBarry Smith   PC_Composite *jac = (PC_Composite *)pc->data;
2905fd66863SKarl Rupp 
2914b9ad928SBarry Smith   PetscFunctionBegin;
2924b9ad928SBarry Smith   jac->alpha = alpha;
2933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2944b9ad928SBarry Smith }
2954b9ad928SBarry Smith 
296d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeSetType_Composite(PC pc, PCCompositeType type)
297d71ae5a4SJacob Faibussowitsch {
298fad69fbaSJed Brown   PC_Composite *jac = (PC_Composite *)pc->data;
299fad69fbaSJed Brown 
3004b9ad928SBarry Smith   PetscFunctionBegin;
3014b9ad928SBarry Smith   if (type == PC_COMPOSITE_ADDITIVE) {
3024b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Additive;
3032533e041SBarry Smith     pc->ops->applytranspose = PCApplyTranspose_Composite_Additive;
304421e10b8SBarry Smith   } else if (type == PC_COMPOSITE_MULTIPLICATIVE || type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) {
3054b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Multiplicative;
3062533e041SBarry Smith     pc->ops->applytranspose = PCApplyTranspose_Composite_Multiplicative;
3074b9ad928SBarry Smith   } else if (type == PC_COMPOSITE_SPECIAL) {
3084b9ad928SBarry Smith     pc->ops->apply          = PCApply_Composite_Special;
3090298fd71SBarry Smith     pc->ops->applytranspose = NULL;
310a7261c6bSprj-   } else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONG, "Unknown composite preconditioner type");
311fad69fbaSJed Brown   jac->type = type;
3123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3134b9ad928SBarry Smith }
3144b9ad928SBarry Smith 
315d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeGetType_Composite(PC pc, PCCompositeType *type)
316d71ae5a4SJacob Faibussowitsch {
317c60c7ad4SBarry Smith   PC_Composite *jac = (PC_Composite *)pc->data;
318c60c7ad4SBarry Smith 
319c60c7ad4SBarry Smith   PetscFunctionBegin;
320c60c7ad4SBarry Smith   *type = jac->type;
3213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
322c60c7ad4SBarry Smith }
323c60c7ad4SBarry Smith 
324d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeAddPC_Composite(PC pc, PC subpc)
325d71ae5a4SJacob Faibussowitsch {
3264b9ad928SBarry Smith   PC_Composite    *jac;
3275a9f2f41SSatish Balay   PC_CompositeLink next, ilink;
32879416396SBarry Smith   PetscInt         cnt = 0;
3292dcb1b2aSMatthew Knepley   const char      *prefix;
330d726e3a5SJed Brown   char             newprefix[20];
3314b9ad928SBarry Smith 
3324b9ad928SBarry Smith   PetscFunctionBegin;
3334dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&ilink));
3340a545947SLisandro Dalcin   ilink->next = NULL;
3358aa07aa6SMatthew G. Knepley   ilink->pc   = subpc;
3364b9ad928SBarry Smith 
3374b9ad928SBarry Smith   jac  = (PC_Composite *)pc->data;
3384b9ad928SBarry Smith   next = jac->head;
3394b9ad928SBarry Smith   if (!next) {
3405a9f2f41SSatish Balay     jac->head       = ilink;
3410298fd71SBarry Smith     ilink->previous = NULL;
3424b9ad928SBarry Smith   } else {
3434b9ad928SBarry Smith     cnt++;
3444b9ad928SBarry Smith     while (next->next) {
3454b9ad928SBarry Smith       next = next->next;
3464b9ad928SBarry Smith       cnt++;
3474b9ad928SBarry Smith     }
3485a9f2f41SSatish Balay     next->next      = ilink;
349421e10b8SBarry Smith     ilink->previous = next;
3504b9ad928SBarry Smith   }
3519566063dSJacob Faibussowitsch   PetscCall(PCGetOptionsPrefix(pc, &prefix));
3529566063dSJacob Faibussowitsch   PetscCall(PCSetOptionsPrefix(subpc, prefix));
3539566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(newprefix, 20, "sub_%d_", (int)cnt));
3549566063dSJacob Faibussowitsch   PetscCall(PCAppendOptionsPrefix(subpc, newprefix));
3559566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)subpc));
3563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3578aa07aa6SMatthew G. Knepley }
3588aa07aa6SMatthew G. Knepley 
359d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeAddPCType_Composite(PC pc, PCType type)
360d71ae5a4SJacob Faibussowitsch {
3618aa07aa6SMatthew G. Knepley   PC subpc;
3628aa07aa6SMatthew G. Knepley 
3638aa07aa6SMatthew G. Knepley   PetscFunctionBegin;
3649566063dSJacob Faibussowitsch   PetscCall(PCCreate(PetscObjectComm((PetscObject)pc), &subpc));
3659566063dSJacob Faibussowitsch   PetscCall(PetscObjectIncrementTabLevel((PetscObject)subpc, (PetscObject)pc, 1));
3669566063dSJacob Faibussowitsch   PetscCall(PCCompositeAddPC_Composite(pc, subpc));
3674b9ad928SBarry Smith   /* type is set after prefix, because some methods may modify prefix, e.g. pcksp */
3689566063dSJacob Faibussowitsch   PetscCall(PCSetType(subpc, type));
3699566063dSJacob Faibussowitsch   PetscCall(PCDestroy(&subpc));
3703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3714b9ad928SBarry Smith }
3724b9ad928SBarry Smith 
373d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeGetNumberPC_Composite(PC pc, PetscInt *n)
374d71ae5a4SJacob Faibussowitsch {
3758e6eba06SBarry Smith   PC_Composite    *jac;
3768e6eba06SBarry Smith   PC_CompositeLink next;
3778e6eba06SBarry Smith 
3788e6eba06SBarry Smith   PetscFunctionBegin;
3798e6eba06SBarry Smith   jac  = (PC_Composite *)pc->data;
3808e6eba06SBarry Smith   next = jac->head;
3818e6eba06SBarry Smith   *n   = 0;
3828e6eba06SBarry Smith   while (next) {
3838e6eba06SBarry Smith     next = next->next;
3848e6eba06SBarry Smith     (*n)++;
3858e6eba06SBarry Smith   }
3863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3878e6eba06SBarry Smith }
3888e6eba06SBarry Smith 
389d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeGetPC_Composite(PC pc, PetscInt n, PC *subpc)
390d71ae5a4SJacob Faibussowitsch {
3914b9ad928SBarry Smith   PC_Composite    *jac;
3924b9ad928SBarry Smith   PC_CompositeLink next;
39379416396SBarry Smith   PetscInt         i;
3944b9ad928SBarry Smith 
3954b9ad928SBarry Smith   PetscFunctionBegin;
3964b9ad928SBarry Smith   jac  = (PC_Composite *)pc->data;
3974b9ad928SBarry Smith   next = jac->head;
3984b9ad928SBarry Smith   for (i = 0; i < n; i++) {
39928b400f6SJacob Faibussowitsch     PetscCheck(next->next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Not enough PCs in composite preconditioner");
4004b9ad928SBarry Smith     next = next->next;
4014b9ad928SBarry Smith   }
4024b9ad928SBarry Smith   *subpc = next->pc;
4033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4044b9ad928SBarry Smith }
4054b9ad928SBarry Smith 
406f39d8e23SSatish Balay /*@
4074b9ad928SBarry Smith   PCCompositeSetType - Sets the type of composite preconditioner.
4084b9ad928SBarry Smith 
409c3339decSBarry Smith   Logically Collective
4104b9ad928SBarry Smith 
411c60c7ad4SBarry Smith   Input Parameters:
4122a6744ebSBarry Smith + pc   - the preconditioner context
413f1580f4eSBarry Smith - type - `PC_COMPOSITE_ADDITIVE` (default), `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL`
4144b9ad928SBarry Smith 
4154b9ad928SBarry Smith   Options Database Key:
4164b9ad928SBarry Smith . -pc_composite_type <type: one of multiplicative, additive, special> - Sets composite preconditioner type
4174b9ad928SBarry Smith 
418f1580f4eSBarry Smith   Level: advanced
4194b9ad928SBarry Smith 
420562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PC_COMPOSITE_ADDITIVE`, `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL`, `PCCompositeType`,
421f1580f4eSBarry Smith           `PCCompositeGetType()`
4224b9ad928SBarry Smith @*/
423d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeSetType(PC pc, PCCompositeType type)
424d71ae5a4SJacob Faibussowitsch {
4254b9ad928SBarry Smith   PetscFunctionBegin;
4260700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
427c5eb9154SBarry Smith   PetscValidLogicalCollectiveEnum(pc, type, 2);
428cac4c232SBarry Smith   PetscTryMethod(pc, "PCCompositeSetType_C", (PC, PCCompositeType), (pc, type));
4293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4304b9ad928SBarry Smith }
4314b9ad928SBarry Smith 
432c60c7ad4SBarry Smith /*@
433721f67b5SBarry Smith   PCCompositeGetType - Gets the type of composite preconditioner.
434c60c7ad4SBarry Smith 
435c3339decSBarry Smith   Logically Collective
436c60c7ad4SBarry Smith 
437c60c7ad4SBarry Smith   Input Parameter:
438c60c7ad4SBarry Smith . pc - the preconditioner context
439c60c7ad4SBarry Smith 
440c60c7ad4SBarry Smith   Output Parameter:
441f1580f4eSBarry Smith . type - `PC_COMPOSITE_ADDITIVE` (default), `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL`
442c60c7ad4SBarry Smith 
443f1580f4eSBarry Smith   Level: advanced
444c60c7ad4SBarry Smith 
445562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PC_COMPOSITE_ADDITIVE`, `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL`, `PCCompositeType`,
446f1580f4eSBarry Smith           `PCCompositeSetType()`
447c60c7ad4SBarry Smith @*/
448d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeGetType(PC pc, PCCompositeType *type)
449d71ae5a4SJacob Faibussowitsch {
450c60c7ad4SBarry Smith   PetscFunctionBegin;
451c60c7ad4SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
452cac4c232SBarry Smith   PetscUseMethod(pc, "PCCompositeGetType_C", (PC, PCCompositeType *), (pc, type));
4533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
454c60c7ad4SBarry Smith }
455c60c7ad4SBarry Smith 
456f39d8e23SSatish Balay /*@
457f1580f4eSBarry Smith   PCCompositeSpecialSetAlpha - Sets alpha for the special composite preconditioner, `PC_COMPOSITE_SPECIAL`,
458af27ebaaSBarry Smith   for $\alpha I + R + S$
4594b9ad928SBarry Smith 
460c3339decSBarry Smith   Logically Collective
4614b9ad928SBarry Smith 
462d8d19677SJose E. Roman   Input Parameters:
4634b9ad928SBarry Smith + pc    - the preconditioner context
4644b9ad928SBarry Smith - alpha - scale on identity
4654b9ad928SBarry Smith 
466feefa0e1SJacob Faibussowitsch   Level: developer
4674b9ad928SBarry Smith 
468562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PC_COMPOSITE_ADDITIVE`, `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL`, `PCCompositeType`,
469f1580f4eSBarry Smith           `PCCompositeSetType()`, `PCCompositeGetType()`
4704b9ad928SBarry Smith @*/
471d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeSpecialSetAlpha(PC pc, PetscScalar alpha)
472d71ae5a4SJacob Faibussowitsch {
4734b9ad928SBarry Smith   PetscFunctionBegin;
4740700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
475c5eb9154SBarry Smith   PetscValidLogicalCollectiveScalar(pc, alpha, 2);
476cac4c232SBarry Smith   PetscTryMethod(pc, "PCCompositeSpecialSetAlpha_C", (PC, PetscScalar), (pc, alpha));
4773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4784b9ad928SBarry Smith }
4794b9ad928SBarry Smith 
4804b9ad928SBarry Smith /*@C
481f1580f4eSBarry Smith   PCCompositeAddPCType - Adds another `PC` of the given type to the composite `PC`.
4824b9ad928SBarry Smith 
483c3339decSBarry Smith   Collective
4844b9ad928SBarry Smith 
4854b9ad928SBarry Smith   Input Parameters:
4862a6744ebSBarry Smith + pc   - the preconditioner context
4872a6744ebSBarry Smith - type - the type of the new preconditioner
4884b9ad928SBarry Smith 
489f1580f4eSBarry Smith   Level: intermediate
4904b9ad928SBarry Smith 
491562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PCCompositeAddPC()`, `PCCompositeGetNumberPC()`
4924b9ad928SBarry Smith @*/
493d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeAddPCType(PC pc, PCType type)
494d71ae5a4SJacob Faibussowitsch {
4954b9ad928SBarry Smith   PetscFunctionBegin;
4960700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
497cac4c232SBarry Smith   PetscTryMethod(pc, "PCCompositeAddPCType_C", (PC, PCType), (pc, type));
4983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4998aa07aa6SMatthew G. Knepley }
5008aa07aa6SMatthew G. Knepley 
5018aa07aa6SMatthew G. Knepley /*@
502f1580f4eSBarry Smith   PCCompositeAddPC - Adds another `PC` to the composite `PC`.
5038aa07aa6SMatthew G. Knepley 
504c3339decSBarry Smith   Collective
5058aa07aa6SMatthew G. Knepley 
5068aa07aa6SMatthew G. Knepley   Input Parameters:
5078aa07aa6SMatthew G. Knepley + pc    - the preconditioner context
5088aa07aa6SMatthew G. Knepley - subpc - the new preconditioner
5098aa07aa6SMatthew G. Knepley 
510f1580f4eSBarry Smith   Level: intermediate
5118aa07aa6SMatthew G. Knepley 
512562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PCCompositeAddPCType()`, `PCCompositeGetNumberPC()`
5138aa07aa6SMatthew G. Knepley @*/
514d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeAddPC(PC pc, PC subpc)
515d71ae5a4SJacob Faibussowitsch {
5168aa07aa6SMatthew G. Knepley   PetscFunctionBegin;
5178aa07aa6SMatthew G. Knepley   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
5188aa07aa6SMatthew G. Knepley   PetscValidHeaderSpecific(subpc, PC_CLASSID, 2);
519cac4c232SBarry Smith   PetscTryMethod(pc, "PCCompositeAddPC_C", (PC, PC), (pc, subpc));
5203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5214b9ad928SBarry Smith }
5224b9ad928SBarry Smith 
5238e6eba06SBarry Smith /*@
524f1580f4eSBarry Smith   PCCompositeGetNumberPC - Gets the number of `PC` objects in the composite `PC`.
5258e6eba06SBarry Smith 
5268e6eba06SBarry Smith   Not Collective
5278e6eba06SBarry Smith 
5288e6eba06SBarry Smith   Input Parameter:
5298e6eba06SBarry Smith . pc - the preconditioner context
5308e6eba06SBarry Smith 
5318e6eba06SBarry Smith   Output Parameter:
5328e6eba06SBarry Smith . num - the number of sub pcs
5338e6eba06SBarry Smith 
534feefa0e1SJacob Faibussowitsch   Level: developer
5358e6eba06SBarry Smith 
536562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PCCompositeGetPC()`, `PCCompositeAddPC()`, `PCCompositeAddPCType()`
5378e6eba06SBarry Smith @*/
538d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeGetNumberPC(PC pc, PetscInt *num)
539d71ae5a4SJacob Faibussowitsch {
5408e6eba06SBarry Smith   PetscFunctionBegin;
5418e6eba06SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
5424f572ea9SToby Isaac   PetscAssertPointer(num, 2);
543cac4c232SBarry Smith   PetscUseMethod(pc, "PCCompositeGetNumberPC_C", (PC, PetscInt *), (pc, num));
5443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5458e6eba06SBarry Smith }
5468e6eba06SBarry Smith 
547f39d8e23SSatish Balay /*@
548f1580f4eSBarry Smith   PCCompositeGetPC - Gets one of the `PC` objects in the composite `PC`.
5494b9ad928SBarry Smith 
5504b9ad928SBarry Smith   Not Collective
5514b9ad928SBarry Smith 
552d8d19677SJose E. Roman   Input Parameters:
5532a6744ebSBarry Smith + pc - the preconditioner context
5542a6744ebSBarry Smith - n  - the number of the pc requested
5554b9ad928SBarry Smith 
556f1580f4eSBarry Smith   Output Parameter:
5574b9ad928SBarry Smith . subpc - the PC requested
5584b9ad928SBarry Smith 
559f1580f4eSBarry Smith   Level: intermediate
5604b9ad928SBarry Smith 
561f1580f4eSBarry Smith   Note:
562f1580f4eSBarry Smith   To use a different operator to construct one of the inner preconditioners first call `PCCompositeGetPC()`, then
563f1580f4eSBarry Smith   call `PCSetOperators()` on that `PC`.
5642b1d202aSBarry Smith 
565562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PCCompositeAddPCType()`, `PCCompositeGetNumberPC()`, `PCSetOperators()`
5664b9ad928SBarry Smith @*/
567d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeGetPC(PC pc, PetscInt n, PC *subpc)
568d71ae5a4SJacob Faibussowitsch {
5694b9ad928SBarry Smith   PetscFunctionBegin;
5700700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
5714f572ea9SToby Isaac   PetscAssertPointer(subpc, 3);
572cac4c232SBarry Smith   PetscUseMethod(pc, "PCCompositeGetPC_C", (PC, PetscInt, PC *), (pc, n, subpc));
5733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5744b9ad928SBarry Smith }
5754b9ad928SBarry Smith 
5764b9ad928SBarry Smith /*MC
5774b9ad928SBarry Smith      PCCOMPOSITE - Build a preconditioner by composing together several preconditioners
5784b9ad928SBarry Smith 
5794b9ad928SBarry Smith    Options Database Keys:
5802eab2d5bSJungho Lee +  -pc_composite_type <type: one of multiplicative, additive, symmetric_multiplicative, special> - Sets composite preconditioner type
581f1580f4eSBarry Smith .  -pc_use_amat                                                                                  - activates `PCSetUseAmat()`
58251f519a2SBarry Smith -  -pc_composite_pcs                                                                             - <pc0,pc1,...> list of PCs to compose
5834b9ad928SBarry Smith 
5844b9ad928SBarry Smith    Level: intermediate
5854b9ad928SBarry Smith 
58695452b02SPatrick Sanan    Notes:
587f1580f4eSBarry Smith    To use a Krylov method inside the composite preconditioner, set the `PCType` of one or more
588f1580f4eSBarry Smith    inner `PC`s to be `PCKSP`. Using a Krylov method inside another Krylov method can be dangerous (you get divergence or
589f1580f4eSBarry Smith    the incorrect answer) unless you use `KSPFGMRES` as the outer Krylov method
590f1580f4eSBarry Smith 
591f1580f4eSBarry Smith    To use a different operator to construct one of the inner preconditioners first call `PCCompositeGetPC()`, then
592f1580f4eSBarry Smith    call `PCSetOperators()` on that `PC`.
5934b9ad928SBarry Smith 
594562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`,
595db781477SPatrick Sanan           `PCSHELL`, `PCKSP`, `PCCompositeSetType()`, `PCCompositeSpecialSetAlpha()`, `PCCompositeAddPCType()`,
596f1580f4eSBarry Smith           `PCCompositeGetPC()`, `PCSetUseAmat()`, `PCCompositeAddPC()`, `PCCompositeGetNumberPC()`
5974b9ad928SBarry Smith M*/
5984b9ad928SBarry Smith 
599d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_Composite(PC pc)
600d71ae5a4SJacob Faibussowitsch {
6014b9ad928SBarry Smith   PC_Composite *jac;
6024b9ad928SBarry Smith 
6034b9ad928SBarry Smith   PetscFunctionBegin;
6044dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&jac));
6052fa5cd67SKarl Rupp 
6064b9ad928SBarry Smith   pc->ops->apply           = PCApply_Composite_Additive;
6072533e041SBarry Smith   pc->ops->applytranspose  = PCApplyTranspose_Composite_Additive;
6084b9ad928SBarry Smith   pc->ops->setup           = PCSetUp_Composite;
6094f853519SStefano Zampini   pc->ops->setuponblocks   = PCSetUpOnBlocks_Composite;
61069d2c0f9SBarry Smith   pc->ops->reset           = PCReset_Composite;
6114b9ad928SBarry Smith   pc->ops->destroy         = PCDestroy_Composite;
6124b9ad928SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Composite;
6134b9ad928SBarry Smith   pc->ops->view            = PCView_Composite;
6140a545947SLisandro Dalcin   pc->ops->applyrichardson = NULL;
6154b9ad928SBarry Smith 
6164b9ad928SBarry Smith   pc->data   = (void *)jac;
6174b9ad928SBarry Smith   jac->type  = PC_COMPOSITE_ADDITIVE;
6180a545947SLisandro Dalcin   jac->work1 = NULL;
6190a545947SLisandro Dalcin   jac->work2 = NULL;
6200a545947SLisandro Dalcin   jac->head  = NULL;
6214b9ad928SBarry Smith 
6229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSetType_C", PCCompositeSetType_Composite));
6239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetType_C", PCCompositeGetType_Composite));
6249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeAddPCType_C", PCCompositeAddPCType_Composite));
6259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeAddPC_C", PCCompositeAddPC_Composite));
6269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetNumberPC_C", PCCompositeGetNumberPC_Composite));
6279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetPC_C", PCCompositeGetPC_Composite));
6289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSpecialSetAlpha_C", PCCompositeSpecialSetAlpha_Composite));
6293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6304b9ad928SBarry Smith }
631