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; 2078a3110eSAlexander Mat alpha_mat; 214b9ad928SBarry Smith } PC_Composite; 224b9ad928SBarry Smith 23d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_Composite_Multiplicative(PC pc, Vec x, Vec y) 24d71ae5a4SJacob Faibussowitsch { 254b9ad928SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 264b9ad928SBarry Smith PC_CompositeLink next = jac->head; 274b9ad928SBarry Smith Mat mat = pc->pmat; 284b9ad928SBarry Smith 294b9ad928SBarry Smith PetscFunctionBegin; 3028b400f6SJacob Faibussowitsch PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs"); 31450d59ebSPatrick Farrell 32450d59ebSPatrick Farrell /* Set the reuse flag on children PCs */ 33450d59ebSPatrick Farrell while (next) { 349566063dSJacob Faibussowitsch PetscCall(PCSetReusePreconditioner(next->pc, pc->reusepreconditioner)); 35450d59ebSPatrick Farrell next = next->next; 36450d59ebSPatrick Farrell } 37450d59ebSPatrick Farrell next = jac->head; 38450d59ebSPatrick Farrell 394b9ad928SBarry Smith if (next->next && !jac->work2) { /* allocate second work vector */ 409566063dSJacob Faibussowitsch PetscCall(VecDuplicate(jac->work1, &jac->work2)); 414b9ad928SBarry Smith } 4249517cdeSBarry Smith if (pc->useAmat) mat = pc->mat; 439566063dSJacob Faibussowitsch PetscCall(PCApply(next->pc, x, y)); /* y <- B x */ 444b9ad928SBarry Smith while (next->next) { 454b9ad928SBarry Smith next = next->next; 469566063dSJacob Faibussowitsch PetscCall(MatMult(mat, y, jac->work1)); /* work1 <- A y */ 479566063dSJacob Faibussowitsch PetscCall(VecWAXPY(jac->work2, -1.0, jac->work1, x)); /* work2 <- x - work1 */ 489566063dSJacob Faibussowitsch PetscCall(PCApply(next->pc, jac->work2, jac->work1)); /* work1 <- C work2 */ 499566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, 1.0, jac->work1)); /* y <- y + work1 = B x + C (x - A B x) = (B + C (1 - A B)) x */ 504b9ad928SBarry Smith } 51421e10b8SBarry Smith if (jac->type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) { 52421e10b8SBarry Smith while (next->previous) { 53421e10b8SBarry Smith next = next->previous; 549566063dSJacob Faibussowitsch PetscCall(MatMult(mat, y, jac->work1)); 559566063dSJacob Faibussowitsch PetscCall(VecWAXPY(jac->work2, -1.0, jac->work1, x)); 569566063dSJacob Faibussowitsch PetscCall(PCApply(next->pc, jac->work2, jac->work1)); 579566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, 1.0, jac->work1)); 58421e10b8SBarry Smith } 59421e10b8SBarry Smith } 603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 614b9ad928SBarry Smith } 624b9ad928SBarry Smith 63d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_Composite_Multiplicative(PC pc, Vec x, Vec y) 64d71ae5a4SJacob Faibussowitsch { 652533e041SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 662533e041SBarry Smith PC_CompositeLink next = jac->head; 672533e041SBarry Smith Mat mat = pc->pmat; 682533e041SBarry Smith 692533e041SBarry Smith PetscFunctionBegin; 7028b400f6SJacob Faibussowitsch PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs"); 712533e041SBarry Smith if (next->next && !jac->work2) { /* allocate second work vector */ 729566063dSJacob Faibussowitsch PetscCall(VecDuplicate(jac->work1, &jac->work2)); 732533e041SBarry Smith } 7449517cdeSBarry Smith if (pc->useAmat) mat = pc->mat; 752533e041SBarry Smith /* locate last PC */ 76ad540459SPierre Jolivet while (next->next) next = next->next; 779566063dSJacob Faibussowitsch PetscCall(PCApplyTranspose(next->pc, x, y)); 782533e041SBarry Smith while (next->previous) { 792533e041SBarry Smith next = next->previous; 809566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(mat, y, jac->work1)); 819566063dSJacob Faibussowitsch PetscCall(VecWAXPY(jac->work2, -1.0, jac->work1, x)); 829566063dSJacob Faibussowitsch PetscCall(PCApplyTranspose(next->pc, jac->work2, jac->work1)); 839566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, 1.0, jac->work1)); 842533e041SBarry Smith } 852533e041SBarry Smith if (jac->type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) { 862533e041SBarry Smith next = jac->head; 872533e041SBarry Smith while (next->next) { 882533e041SBarry Smith next = next->next; 899566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(mat, y, jac->work1)); 909566063dSJacob Faibussowitsch PetscCall(VecWAXPY(jac->work2, -1.0, jac->work1, x)); 919566063dSJacob Faibussowitsch PetscCall(PCApplyTranspose(next->pc, jac->work2, jac->work1)); 929566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, 1.0, jac->work1)); 932533e041SBarry Smith } 942533e041SBarry Smith } 953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 962533e041SBarry Smith } 972533e041SBarry Smith 984b9ad928SBarry Smith /* 994b9ad928SBarry Smith This is very special for a matrix of the form alpha I + R + S 1004b9ad928SBarry Smith where first preconditioner is built from alpha I + S and second from 1014b9ad928SBarry Smith alpha I + R 1024b9ad928SBarry Smith */ 103d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_Composite_Special(PC pc, Vec x, Vec y) 104d71ae5a4SJacob Faibussowitsch { 1054b9ad928SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 1064b9ad928SBarry Smith PC_CompositeLink next = jac->head; 1074b9ad928SBarry Smith 1084b9ad928SBarry Smith PetscFunctionBegin; 10928b400f6SJacob Faibussowitsch PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs"); 1107827d75bSBarry Smith PetscCheck(next->next && !next->next->next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Special composite preconditioners requires exactly two PCs"); 1114b9ad928SBarry Smith 112450d59ebSPatrick Farrell /* Set the reuse flag on children PCs */ 1139566063dSJacob Faibussowitsch PetscCall(PCSetReusePreconditioner(next->pc, pc->reusepreconditioner)); 1149566063dSJacob Faibussowitsch PetscCall(PCSetReusePreconditioner(next->next->pc, pc->reusepreconditioner)); 115450d59ebSPatrick Farrell 1169566063dSJacob Faibussowitsch PetscCall(PCApply(next->pc, x, jac->work1)); 11778a3110eSAlexander if (jac->alpha_mat) { 11878a3110eSAlexander if (!jac->work2) PetscCall(VecDuplicate(jac->work1, &jac->work2)); 11978a3110eSAlexander PetscCall(MatMult(jac->alpha_mat, jac->work1, jac->work2)); 12078a3110eSAlexander PetscCall(PCApply(next->next->pc, jac->work2, y)); 12178a3110eSAlexander } else PetscCall(PCApply(next->next->pc, jac->work1, y)); 1223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1234b9ad928SBarry Smith } 1244b9ad928SBarry Smith 125d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_Composite_Additive(PC pc, Vec x, Vec y) 126d71ae5a4SJacob Faibussowitsch { 1274b9ad928SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 1284b9ad928SBarry Smith PC_CompositeLink next = jac->head; 1294b9ad928SBarry Smith 1304b9ad928SBarry Smith PetscFunctionBegin; 13128b400f6SJacob Faibussowitsch PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs"); 132450d59ebSPatrick Farrell 133450d59ebSPatrick Farrell /* Set the reuse flag on children PCs */ 134450d59ebSPatrick Farrell while (next) { 1359566063dSJacob Faibussowitsch PetscCall(PCSetReusePreconditioner(next->pc, pc->reusepreconditioner)); 136450d59ebSPatrick Farrell next = next->next; 137450d59ebSPatrick Farrell } 138450d59ebSPatrick Farrell next = jac->head; 139450d59ebSPatrick Farrell 1409566063dSJacob Faibussowitsch PetscCall(PCApply(next->pc, x, y)); 1414b9ad928SBarry Smith while (next->next) { 1424b9ad928SBarry Smith next = next->next; 1439566063dSJacob Faibussowitsch PetscCall(PCApply(next->pc, x, jac->work1)); 1449566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, 1.0, jac->work1)); 1454b9ad928SBarry Smith } 1463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1474b9ad928SBarry Smith } 1484b9ad928SBarry Smith 149d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_Composite_Additive(PC pc, Vec x, Vec y) 150d71ae5a4SJacob Faibussowitsch { 1512533e041SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 1522533e041SBarry Smith PC_CompositeLink next = jac->head; 1532533e041SBarry Smith 1542533e041SBarry Smith PetscFunctionBegin; 15528b400f6SJacob Faibussowitsch PetscCheck(next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "No composite preconditioners supplied via PCCompositeAddPCType() or -pc_composite_pcs"); 1569566063dSJacob Faibussowitsch PetscCall(PCApplyTranspose(next->pc, x, y)); 1572533e041SBarry Smith while (next->next) { 1582533e041SBarry Smith next = next->next; 1599566063dSJacob Faibussowitsch PetscCall(PCApplyTranspose(next->pc, x, jac->work1)); 1609566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, 1.0, jac->work1)); 1612533e041SBarry Smith } 1623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1632533e041SBarry Smith } 1642533e041SBarry Smith 165d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_Composite(PC pc) 166d71ae5a4SJacob Faibussowitsch { 1674b9ad928SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 1684b9ad928SBarry Smith PC_CompositeLink next = jac->head; 1695a78d018SMatthew G. Knepley DM dm; 1704b9ad928SBarry Smith 1714b9ad928SBarry Smith PetscFunctionBegin; 17248a46eb9SPierre Jolivet if (!jac->work1) PetscCall(MatCreateVecs(pc->pmat, &jac->work1, NULL)); 1739566063dSJacob Faibussowitsch PetscCall(PCGetDM(pc, &dm)); 1744b9ad928SBarry Smith while (next) { 17548a46eb9SPierre Jolivet if (!next->pc->dm) PetscCall(PCSetDM(next->pc, dm)); 17648a46eb9SPierre Jolivet if (!next->pc->mat) PetscCall(PCSetOperators(next->pc, pc->mat, pc->pmat)); 1774b9ad928SBarry Smith next = next->next; 1784b9ad928SBarry Smith } 1793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1804b9ad928SBarry Smith } 1814b9ad928SBarry Smith 1824f853519SStefano Zampini static PetscErrorCode PCSetUpOnBlocks_Composite(PC pc) 1834f853519SStefano Zampini { 1844f853519SStefano Zampini PC_Composite *jac = (PC_Composite *)pc->data; 1854f853519SStefano Zampini PC_CompositeLink next = jac->head; 1864f853519SStefano Zampini PCFailedReason reason; 1874f853519SStefano Zampini 1884f853519SStefano Zampini PetscFunctionBegin; 1894f853519SStefano Zampini while (next) { 1904f853519SStefano Zampini PetscCall(PCSetUp(next->pc)); 1919a6c2652SBarry Smith PetscCall(PCGetFailedReason(next->pc, &reason)); 1924f853519SStefano Zampini if (reason) pc->failedreason = reason; 1934f853519SStefano Zampini next = next->next; 1944f853519SStefano Zampini } 1954f853519SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 1964f853519SStefano Zampini } 1974f853519SStefano Zampini 198d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_Composite(PC pc) 199d71ae5a4SJacob Faibussowitsch { 20069d2c0f9SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 2015f48b12bSBarry Smith PC_CompositeLink next = jac->head; 20269d2c0f9SBarry Smith 20369d2c0f9SBarry Smith PetscFunctionBegin; 20469d2c0f9SBarry Smith while (next) { 2059566063dSJacob Faibussowitsch PetscCall(PCReset(next->pc)); 20669d2c0f9SBarry Smith next = next->next; 20769d2c0f9SBarry Smith } 2089566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->work1)); 2099566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->work2)); 21078a3110eSAlexander PetscCall(MatDestroy(&jac->alpha_mat)); 2113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21269d2c0f9SBarry Smith } 21369d2c0f9SBarry Smith 214d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_Composite(PC pc) 215d71ae5a4SJacob Faibussowitsch { 2164b9ad928SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 217724c2c99SHong Zhang PC_CompositeLink next = jac->head, next_tmp; 2184b9ad928SBarry Smith 2194b9ad928SBarry Smith PetscFunctionBegin; 2209566063dSJacob Faibussowitsch PetscCall(PCReset_Composite(pc)); 2214b9ad928SBarry Smith while (next) { 2229566063dSJacob Faibussowitsch PetscCall(PCDestroy(&next->pc)); 223724c2c99SHong Zhang next_tmp = next; 2244b9ad928SBarry Smith next = next->next; 2259566063dSJacob Faibussowitsch PetscCall(PetscFree(next_tmp)); 2264b9ad928SBarry Smith } 2272e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSetType_C", NULL)); 2282e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetType_C", NULL)); 2292e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeAddPCType_C", NULL)); 2302e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeAddPC_C", NULL)); 2312e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetNumberPC_C", NULL)); 2322e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetPC_C", NULL)); 2332e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSpecialSetAlpha_C", NULL)); 23478a3110eSAlexander PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSpecialSetAlphaMat_C", NULL)); 2359566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 2363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2374b9ad928SBarry Smith } 2384b9ad928SBarry Smith 239ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_Composite(PC pc, PetscOptionItems PetscOptionsObject) 240d71ae5a4SJacob Faibussowitsch { 2414b9ad928SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 242fe972ab9SMatthew G. Knepley PetscInt nmax, i; 2434b9ad928SBarry Smith PC_CompositeLink next; 244fe972ab9SMatthew G. Knepley char *pcs[1024]; 245ace3abfcSBarry Smith PetscBool flg; 2464b9ad928SBarry Smith 2474b9ad928SBarry Smith PetscFunctionBegin; 248d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "Composite preconditioner options"); 2499566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-pc_composite_type", "Type of composition", "PCCompositeSetType", PCCompositeTypes, (PetscEnum)jac->type, (PetscEnum *)&jac->type, &flg)); 2501baa6e33SBarry Smith if (flg) PetscCall(PCCompositeSetType(pc, jac->type)); 251fe972ab9SMatthew G. Knepley nmax = (PetscInt)PETSC_STATIC_ARRAY_LENGTH(pcs); 2529566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringArray("-pc_composite_pcs", "List of composite solvers", "PCCompositeAddPCType", pcs, &nmax, &flg)); 2534b9ad928SBarry Smith if (flg) { 2544b9ad928SBarry Smith for (i = 0; i < nmax; i++) { 2559566063dSJacob Faibussowitsch PetscCall(PCCompositeAddPCType(pc, pcs[i])); 2569566063dSJacob Faibussowitsch PetscCall(PetscFree(pcs[i])); /* deallocate string pcs[i], which is allocated in PetscOptionsStringArray() */ 2574b9ad928SBarry Smith } 2584b9ad928SBarry Smith } 259d0609cedSBarry Smith PetscOptionsHeadEnd(); 2604b9ad928SBarry Smith 2614b9ad928SBarry Smith next = jac->head; 2624b9ad928SBarry Smith while (next) { 2639566063dSJacob Faibussowitsch PetscCall(PCSetFromOptions(next->pc)); 2644b9ad928SBarry Smith next = next->next; 2654b9ad928SBarry Smith } 2663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2674b9ad928SBarry Smith } 2684b9ad928SBarry Smith 269d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_Composite(PC pc, PetscViewer viewer) 270d71ae5a4SJacob Faibussowitsch { 2714b9ad928SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 2724b9ad928SBarry Smith PC_CompositeLink next = jac->head; 273*9f196a02SMartin Diehl PetscBool isascii; 2744b9ad928SBarry Smith 2754b9ad928SBarry Smith PetscFunctionBegin; 276*9f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 277*9f196a02SMartin Diehl if (isascii) { 2789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Composite PC type - %s\n", PCCompositeTypes[jac->type])); 2799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "PCs on composite preconditioner follow\n")); 2809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "---------------------------------\n")); 2814b9ad928SBarry Smith } 282*9f196a02SMartin Diehl if (isascii) PetscCall(PetscViewerASCIIPushTab(viewer)); 2834b9ad928SBarry Smith while (next) { 2849566063dSJacob Faibussowitsch PetscCall(PCView(next->pc, viewer)); 2854b9ad928SBarry Smith next = next->next; 2864b9ad928SBarry Smith } 287*9f196a02SMartin Diehl if (isascii) { 2889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 2899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "---------------------------------\n")); 2904b9ad928SBarry Smith } 2913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2924b9ad928SBarry Smith } 2934b9ad928SBarry Smith 294d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeSpecialSetAlpha_Composite(PC pc, PetscScalar alpha) 295d71ae5a4SJacob Faibussowitsch { 2964b9ad928SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 2975fd66863SKarl Rupp 2984b9ad928SBarry Smith PetscFunctionBegin; 2994b9ad928SBarry Smith jac->alpha = alpha; 3003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3014b9ad928SBarry Smith } 3024b9ad928SBarry Smith 30378a3110eSAlexander static PetscErrorCode PCCompositeSpecialSetAlphaMat_Composite(PC pc, Mat alpha_mat) 30478a3110eSAlexander { 30578a3110eSAlexander PC_Composite *jac = (PC_Composite *)pc->data; 30678a3110eSAlexander 30778a3110eSAlexander PetscFunctionBegin; 30878a3110eSAlexander if (alpha_mat) { 30978a3110eSAlexander PetscValidHeaderSpecific(alpha_mat, MAT_CLASSID, 2); 31078a3110eSAlexander PetscCall(PetscObjectReference((PetscObject)alpha_mat)); 31178a3110eSAlexander } 31278a3110eSAlexander PetscCall(MatDestroy(&jac->alpha_mat)); 31378a3110eSAlexander jac->alpha_mat = alpha_mat; 31478a3110eSAlexander PetscFunctionReturn(PETSC_SUCCESS); 31578a3110eSAlexander } 31678a3110eSAlexander 317d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeSetType_Composite(PC pc, PCCompositeType type) 318d71ae5a4SJacob Faibussowitsch { 319fad69fbaSJed Brown PC_Composite *jac = (PC_Composite *)pc->data; 320fad69fbaSJed Brown 3214b9ad928SBarry Smith PetscFunctionBegin; 3224b9ad928SBarry Smith if (type == PC_COMPOSITE_ADDITIVE) { 3234b9ad928SBarry Smith pc->ops->apply = PCApply_Composite_Additive; 3242533e041SBarry Smith pc->ops->applytranspose = PCApplyTranspose_Composite_Additive; 325421e10b8SBarry Smith } else if (type == PC_COMPOSITE_MULTIPLICATIVE || type == PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE) { 3264b9ad928SBarry Smith pc->ops->apply = PCApply_Composite_Multiplicative; 3272533e041SBarry Smith pc->ops->applytranspose = PCApplyTranspose_Composite_Multiplicative; 3284b9ad928SBarry Smith } else if (type == PC_COMPOSITE_SPECIAL) { 3294b9ad928SBarry Smith pc->ops->apply = PCApply_Composite_Special; 3300298fd71SBarry Smith pc->ops->applytranspose = NULL; 331a7261c6bSprj- } else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONG, "Unknown composite preconditioner type"); 332fad69fbaSJed Brown jac->type = type; 3333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3344b9ad928SBarry Smith } 3354b9ad928SBarry Smith 336d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeGetType_Composite(PC pc, PCCompositeType *type) 337d71ae5a4SJacob Faibussowitsch { 338c60c7ad4SBarry Smith PC_Composite *jac = (PC_Composite *)pc->data; 339c60c7ad4SBarry Smith 340c60c7ad4SBarry Smith PetscFunctionBegin; 341c60c7ad4SBarry Smith *type = jac->type; 3423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 343c60c7ad4SBarry Smith } 344c60c7ad4SBarry Smith 345d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeAddPC_Composite(PC pc, PC subpc) 346d71ae5a4SJacob Faibussowitsch { 3474b9ad928SBarry Smith PC_Composite *jac; 3485a9f2f41SSatish Balay PC_CompositeLink next, ilink; 34979416396SBarry Smith PetscInt cnt = 0; 3502dcb1b2aSMatthew Knepley const char *prefix; 351d726e3a5SJed Brown char newprefix[20]; 3524b9ad928SBarry Smith 3534b9ad928SBarry Smith PetscFunctionBegin; 3544dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ilink)); 3550a545947SLisandro Dalcin ilink->next = NULL; 3568aa07aa6SMatthew G. Knepley ilink->pc = subpc; 3574b9ad928SBarry Smith 3584b9ad928SBarry Smith jac = (PC_Composite *)pc->data; 3594b9ad928SBarry Smith next = jac->head; 3604b9ad928SBarry Smith if (!next) { 3615a9f2f41SSatish Balay jac->head = ilink; 3620298fd71SBarry Smith ilink->previous = NULL; 3634b9ad928SBarry Smith } else { 3644b9ad928SBarry Smith cnt++; 3654b9ad928SBarry Smith while (next->next) { 3664b9ad928SBarry Smith next = next->next; 3674b9ad928SBarry Smith cnt++; 3684b9ad928SBarry Smith } 3695a9f2f41SSatish Balay next->next = ilink; 370421e10b8SBarry Smith ilink->previous = next; 3714b9ad928SBarry Smith } 3729566063dSJacob Faibussowitsch PetscCall(PCGetOptionsPrefix(pc, &prefix)); 3739566063dSJacob Faibussowitsch PetscCall(PCSetOptionsPrefix(subpc, prefix)); 374835f2295SStefano Zampini PetscCall(PetscSNPrintf(newprefix, 20, "sub_%" PetscInt_FMT "_", cnt)); 3759566063dSJacob Faibussowitsch PetscCall(PCAppendOptionsPrefix(subpc, newprefix)); 3769566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)subpc)); 3773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3788aa07aa6SMatthew G. Knepley } 3798aa07aa6SMatthew G. Knepley 380d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeAddPCType_Composite(PC pc, PCType type) 381d71ae5a4SJacob Faibussowitsch { 3828aa07aa6SMatthew G. Knepley PC subpc; 3838aa07aa6SMatthew G. Knepley 3848aa07aa6SMatthew G. Knepley PetscFunctionBegin; 3859566063dSJacob Faibussowitsch PetscCall(PCCreate(PetscObjectComm((PetscObject)pc), &subpc)); 3869566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)subpc, (PetscObject)pc, 1)); 3879566063dSJacob Faibussowitsch PetscCall(PCCompositeAddPC_Composite(pc, subpc)); 3884b9ad928SBarry Smith /* type is set after prefix, because some methods may modify prefix, e.g. pcksp */ 3899566063dSJacob Faibussowitsch PetscCall(PCSetType(subpc, type)); 3909566063dSJacob Faibussowitsch PetscCall(PCDestroy(&subpc)); 3913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3924b9ad928SBarry Smith } 3934b9ad928SBarry Smith 394d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeGetNumberPC_Composite(PC pc, PetscInt *n) 395d71ae5a4SJacob Faibussowitsch { 3968e6eba06SBarry Smith PC_Composite *jac; 3978e6eba06SBarry Smith PC_CompositeLink next; 3988e6eba06SBarry Smith 3998e6eba06SBarry Smith PetscFunctionBegin; 4008e6eba06SBarry Smith jac = (PC_Composite *)pc->data; 4018e6eba06SBarry Smith next = jac->head; 4028e6eba06SBarry Smith *n = 0; 4038e6eba06SBarry Smith while (next) { 4048e6eba06SBarry Smith next = next->next; 4058e6eba06SBarry Smith (*n)++; 4068e6eba06SBarry Smith } 4073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4088e6eba06SBarry Smith } 4098e6eba06SBarry Smith 410d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCCompositeGetPC_Composite(PC pc, PetscInt n, PC *subpc) 411d71ae5a4SJacob Faibussowitsch { 4124b9ad928SBarry Smith PC_Composite *jac; 4134b9ad928SBarry Smith PC_CompositeLink next; 41479416396SBarry Smith PetscInt i; 4154b9ad928SBarry Smith 4164b9ad928SBarry Smith PetscFunctionBegin; 4174b9ad928SBarry Smith jac = (PC_Composite *)pc->data; 4184b9ad928SBarry Smith next = jac->head; 4194b9ad928SBarry Smith for (i = 0; i < n; i++) { 42028b400f6SJacob Faibussowitsch PetscCheck(next->next, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Not enough PCs in composite preconditioner"); 4214b9ad928SBarry Smith next = next->next; 4224b9ad928SBarry Smith } 4234b9ad928SBarry Smith *subpc = next->pc; 4243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4254b9ad928SBarry Smith } 4264b9ad928SBarry Smith 427f39d8e23SSatish Balay /*@ 4284b9ad928SBarry Smith PCCompositeSetType - Sets the type of composite preconditioner. 4294b9ad928SBarry Smith 430c3339decSBarry Smith Logically Collective 4314b9ad928SBarry Smith 432c60c7ad4SBarry Smith Input Parameters: 4332a6744ebSBarry Smith + pc - the preconditioner context 434f1580f4eSBarry Smith - type - `PC_COMPOSITE_ADDITIVE` (default), `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL` 4354b9ad928SBarry Smith 4364b9ad928SBarry Smith Options Database Key: 4374b9ad928SBarry Smith . -pc_composite_type <type: one of multiplicative, additive, special> - Sets composite preconditioner type 4384b9ad928SBarry Smith 439f1580f4eSBarry Smith Level: advanced 4404b9ad928SBarry Smith 441562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PC_COMPOSITE_ADDITIVE`, `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL`, `PCCompositeType`, 442f1580f4eSBarry Smith `PCCompositeGetType()` 4434b9ad928SBarry Smith @*/ 444d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeSetType(PC pc, PCCompositeType type) 445d71ae5a4SJacob Faibussowitsch { 4464b9ad928SBarry Smith PetscFunctionBegin; 4470700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 448c5eb9154SBarry Smith PetscValidLogicalCollectiveEnum(pc, type, 2); 449cac4c232SBarry Smith PetscTryMethod(pc, "PCCompositeSetType_C", (PC, PCCompositeType), (pc, type)); 4503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4514b9ad928SBarry Smith } 4524b9ad928SBarry Smith 453c60c7ad4SBarry Smith /*@ 454721f67b5SBarry Smith PCCompositeGetType - Gets the type of composite preconditioner. 455c60c7ad4SBarry Smith 456c3339decSBarry Smith Logically Collective 457c60c7ad4SBarry Smith 458c60c7ad4SBarry Smith Input Parameter: 459c60c7ad4SBarry Smith . pc - the preconditioner context 460c60c7ad4SBarry Smith 461c60c7ad4SBarry Smith Output Parameter: 462f1580f4eSBarry Smith . type - `PC_COMPOSITE_ADDITIVE` (default), `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL` 463c60c7ad4SBarry Smith 464f1580f4eSBarry Smith Level: advanced 465c60c7ad4SBarry Smith 466562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PC_COMPOSITE_ADDITIVE`, `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL`, `PCCompositeType`, 467f1580f4eSBarry Smith `PCCompositeSetType()` 468c60c7ad4SBarry Smith @*/ 469d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeGetType(PC pc, PCCompositeType *type) 470d71ae5a4SJacob Faibussowitsch { 471c60c7ad4SBarry Smith PetscFunctionBegin; 472c60c7ad4SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 473cac4c232SBarry Smith PetscUseMethod(pc, "PCCompositeGetType_C", (PC, PCCompositeType *), (pc, type)); 4743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 475c60c7ad4SBarry Smith } 476c60c7ad4SBarry Smith 477f39d8e23SSatish Balay /*@ 478f1580f4eSBarry Smith PCCompositeSpecialSetAlpha - Sets alpha for the special composite preconditioner, `PC_COMPOSITE_SPECIAL`, 479af27ebaaSBarry Smith for $\alpha I + R + S$ 4804b9ad928SBarry Smith 481c3339decSBarry Smith Logically Collective 4824b9ad928SBarry Smith 483d8d19677SJose E. Roman Input Parameters: 4844b9ad928SBarry Smith + pc - the preconditioner context 4854b9ad928SBarry Smith - alpha - scale on identity 4864b9ad928SBarry Smith 487feefa0e1SJacob Faibussowitsch Level: developer 4884b9ad928SBarry Smith 489562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PC_COMPOSITE_ADDITIVE`, `PC_COMPOSITE_MULTIPLICATIVE`, `PC_COMPOSITE_SPECIAL`, `PCCompositeType`, 490f1580f4eSBarry Smith `PCCompositeSetType()`, `PCCompositeGetType()` 4914b9ad928SBarry Smith @*/ 492d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeSpecialSetAlpha(PC pc, PetscScalar alpha) 493d71ae5a4SJacob Faibussowitsch { 4944b9ad928SBarry Smith PetscFunctionBegin; 4950700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 496c5eb9154SBarry Smith PetscValidLogicalCollectiveScalar(pc, alpha, 2); 497cac4c232SBarry Smith PetscTryMethod(pc, "PCCompositeSpecialSetAlpha_C", (PC, PetscScalar), (pc, alpha)); 4983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4994b9ad928SBarry Smith } 5004b9ad928SBarry Smith 50178a3110eSAlexander PetscErrorCode PCCompositeSpecialSetAlphaMat(PC pc, Mat alpha_mat) 50278a3110eSAlexander { 50378a3110eSAlexander PetscFunctionBegin; 50478a3110eSAlexander PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 50578a3110eSAlexander PetscTryMethod(pc, "PCCompositeSpecialSetAlphaMat_C", (PC, Mat), (pc, alpha_mat)); 50678a3110eSAlexander PetscFunctionReturn(PETSC_SUCCESS); 50778a3110eSAlexander } 50878a3110eSAlexander 5094b9ad928SBarry Smith /*@C 510f1580f4eSBarry Smith PCCompositeAddPCType - Adds another `PC` of the given type to the composite `PC`. 5114b9ad928SBarry Smith 512c3339decSBarry Smith Collective 5134b9ad928SBarry Smith 5144b9ad928SBarry Smith Input Parameters: 5152a6744ebSBarry Smith + pc - the preconditioner context 5162a6744ebSBarry Smith - type - the type of the new preconditioner 5174b9ad928SBarry Smith 518f1580f4eSBarry Smith Level: intermediate 5194b9ad928SBarry Smith 520562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PCCompositeAddPC()`, `PCCompositeGetNumberPC()` 5214b9ad928SBarry Smith @*/ 522d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeAddPCType(PC pc, PCType type) 523d71ae5a4SJacob Faibussowitsch { 5244b9ad928SBarry Smith PetscFunctionBegin; 5250700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 526cac4c232SBarry Smith PetscTryMethod(pc, "PCCompositeAddPCType_C", (PC, PCType), (pc, type)); 5273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5288aa07aa6SMatthew G. Knepley } 5298aa07aa6SMatthew G. Knepley 5308aa07aa6SMatthew G. Knepley /*@ 531f1580f4eSBarry Smith PCCompositeAddPC - Adds another `PC` to the composite `PC`. 5328aa07aa6SMatthew G. Knepley 533c3339decSBarry Smith Collective 5348aa07aa6SMatthew G. Knepley 5358aa07aa6SMatthew G. Knepley Input Parameters: 5368aa07aa6SMatthew G. Knepley + pc - the preconditioner context 5378aa07aa6SMatthew G. Knepley - subpc - the new preconditioner 5388aa07aa6SMatthew G. Knepley 539f1580f4eSBarry Smith Level: intermediate 5408aa07aa6SMatthew G. Knepley 541562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PCCompositeAddPCType()`, `PCCompositeGetNumberPC()` 5428aa07aa6SMatthew G. Knepley @*/ 543d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeAddPC(PC pc, PC subpc) 544d71ae5a4SJacob Faibussowitsch { 5458aa07aa6SMatthew G. Knepley PetscFunctionBegin; 5468aa07aa6SMatthew G. Knepley PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 5478aa07aa6SMatthew G. Knepley PetscValidHeaderSpecific(subpc, PC_CLASSID, 2); 548cac4c232SBarry Smith PetscTryMethod(pc, "PCCompositeAddPC_C", (PC, PC), (pc, subpc)); 5493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5504b9ad928SBarry Smith } 5514b9ad928SBarry Smith 5528e6eba06SBarry Smith /*@ 553f1580f4eSBarry Smith PCCompositeGetNumberPC - Gets the number of `PC` objects in the composite `PC`. 5548e6eba06SBarry Smith 5558e6eba06SBarry Smith Not Collective 5568e6eba06SBarry Smith 5578e6eba06SBarry Smith Input Parameter: 5588e6eba06SBarry Smith . pc - the preconditioner context 5598e6eba06SBarry Smith 5608e6eba06SBarry Smith Output Parameter: 5618e6eba06SBarry Smith . num - the number of sub pcs 5628e6eba06SBarry Smith 563feefa0e1SJacob Faibussowitsch Level: developer 5648e6eba06SBarry Smith 565562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PCCompositeGetPC()`, `PCCompositeAddPC()`, `PCCompositeAddPCType()` 5668e6eba06SBarry Smith @*/ 567d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeGetNumberPC(PC pc, PetscInt *num) 568d71ae5a4SJacob Faibussowitsch { 5698e6eba06SBarry Smith PetscFunctionBegin; 5708e6eba06SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 5714f572ea9SToby Isaac PetscAssertPointer(num, 2); 572cac4c232SBarry Smith PetscUseMethod(pc, "PCCompositeGetNumberPC_C", (PC, PetscInt *), (pc, num)); 5733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5748e6eba06SBarry Smith } 5758e6eba06SBarry Smith 576f39d8e23SSatish Balay /*@ 577f1580f4eSBarry Smith PCCompositeGetPC - Gets one of the `PC` objects in the composite `PC`. 5784b9ad928SBarry Smith 5794b9ad928SBarry Smith Not Collective 5804b9ad928SBarry Smith 581d8d19677SJose E. Roman Input Parameters: 5822a6744ebSBarry Smith + pc - the preconditioner context 5832a6744ebSBarry Smith - n - the number of the pc requested 5844b9ad928SBarry Smith 585f1580f4eSBarry Smith Output Parameter: 5864b9ad928SBarry Smith . subpc - the PC requested 5874b9ad928SBarry Smith 588f1580f4eSBarry Smith Level: intermediate 5894b9ad928SBarry Smith 590f1580f4eSBarry Smith Note: 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`. 5932b1d202aSBarry Smith 594562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCOMPOSITE`, `PCCompositeAddPCType()`, `PCCompositeGetNumberPC()`, `PCSetOperators()` 5954b9ad928SBarry Smith @*/ 596d71ae5a4SJacob Faibussowitsch PetscErrorCode PCCompositeGetPC(PC pc, PetscInt n, PC *subpc) 597d71ae5a4SJacob Faibussowitsch { 5984b9ad928SBarry Smith PetscFunctionBegin; 5990700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 6004f572ea9SToby Isaac PetscAssertPointer(subpc, 3); 601cac4c232SBarry Smith PetscUseMethod(pc, "PCCompositeGetPC_C", (PC, PetscInt, PC *), (pc, n, subpc)); 6023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6034b9ad928SBarry Smith } 6044b9ad928SBarry Smith 6054b9ad928SBarry Smith /*MC 6064b9ad928SBarry Smith PCCOMPOSITE - Build a preconditioner by composing together several preconditioners 6074b9ad928SBarry Smith 6084b9ad928SBarry Smith Options Database Keys: 6092eab2d5bSJungho Lee + -pc_composite_type <type: one of multiplicative, additive, symmetric_multiplicative, special> - Sets composite preconditioner type 610f1580f4eSBarry Smith . -pc_use_amat - activates `PCSetUseAmat()` 61151f519a2SBarry Smith - -pc_composite_pcs - <pc0,pc1,...> list of PCs to compose 6124b9ad928SBarry Smith 6134b9ad928SBarry Smith Level: intermediate 6144b9ad928SBarry Smith 61595452b02SPatrick Sanan Notes: 616f1580f4eSBarry Smith To use a Krylov method inside the composite preconditioner, set the `PCType` of one or more 617f1580f4eSBarry Smith inner `PC`s to be `PCKSP`. Using a Krylov method inside another Krylov method can be dangerous (you get divergence or 618f1580f4eSBarry Smith the incorrect answer) unless you use `KSPFGMRES` as the outer Krylov method 619f1580f4eSBarry Smith 620f1580f4eSBarry Smith To use a different operator to construct one of the inner preconditioners first call `PCCompositeGetPC()`, then 621f1580f4eSBarry Smith call `PCSetOperators()` on that `PC`. 6224b9ad928SBarry Smith 623562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, 624db781477SPatrick Sanan `PCSHELL`, `PCKSP`, `PCCompositeSetType()`, `PCCompositeSpecialSetAlpha()`, `PCCompositeAddPCType()`, 625f1580f4eSBarry Smith `PCCompositeGetPC()`, `PCSetUseAmat()`, `PCCompositeAddPC()`, `PCCompositeGetNumberPC()` 6264b9ad928SBarry Smith M*/ 6274b9ad928SBarry Smith 628d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_Composite(PC pc) 629d71ae5a4SJacob Faibussowitsch { 6304b9ad928SBarry Smith PC_Composite *jac; 6314b9ad928SBarry Smith 6324b9ad928SBarry Smith PetscFunctionBegin; 6334dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac)); 6342fa5cd67SKarl Rupp 6354b9ad928SBarry Smith pc->ops->apply = PCApply_Composite_Additive; 6362533e041SBarry Smith pc->ops->applytranspose = PCApplyTranspose_Composite_Additive; 6374b9ad928SBarry Smith pc->ops->setup = PCSetUp_Composite; 6384f853519SStefano Zampini pc->ops->setuponblocks = PCSetUpOnBlocks_Composite; 63969d2c0f9SBarry Smith pc->ops->reset = PCReset_Composite; 6404b9ad928SBarry Smith pc->ops->destroy = PCDestroy_Composite; 6414b9ad928SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_Composite; 6424b9ad928SBarry Smith pc->ops->view = PCView_Composite; 6430a545947SLisandro Dalcin pc->ops->applyrichardson = NULL; 6444b9ad928SBarry Smith 6454b9ad928SBarry Smith pc->data = (void *)jac; 6464b9ad928SBarry Smith jac->type = PC_COMPOSITE_ADDITIVE; 6470a545947SLisandro Dalcin jac->work1 = NULL; 6480a545947SLisandro Dalcin jac->work2 = NULL; 6490a545947SLisandro Dalcin jac->head = NULL; 65078a3110eSAlexander jac->alpha_mat = NULL; 6514b9ad928SBarry Smith 6529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSetType_C", PCCompositeSetType_Composite)); 6539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetType_C", PCCompositeGetType_Composite)); 6549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeAddPCType_C", PCCompositeAddPCType_Composite)); 6559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeAddPC_C", PCCompositeAddPC_Composite)); 6569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetNumberPC_C", PCCompositeGetNumberPC_Composite)); 6579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeGetPC_C", PCCompositeGetPC_Composite)); 6589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSpecialSetAlpha_C", PCCompositeSpecialSetAlpha_Composite)); 65978a3110eSAlexander PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCCompositeSpecialSetAlphaMat_C", PCCompositeSpecialSetAlphaMat_Composite)); 6603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6614b9ad928SBarry Smith } 662