12a6744ebSBarry Smith 22a6744ebSBarry Smith /* 32a6744ebSBarry Smith Defines a preconditioner defined by R^T S R 42a6744ebSBarry Smith */ 5af0996ceSBarry Smith #include <petsc/private/pcimpl.h> 6c6db04a5SJed Brown #include <petscksp.h> /*I "petscksp.h" I*/ 72a6744ebSBarry Smith 82a6744ebSBarry Smith typedef struct { 92a6744ebSBarry Smith KSP ksp; 102a6744ebSBarry Smith Mat R, P; 112a6744ebSBarry Smith Vec b, x; 12b3402f20SBarry Smith PetscErrorCode (*computeasub)(PC, Mat, Mat, Mat *, void *); 13b3402f20SBarry Smith void *computeasub_ctx; 142a6744ebSBarry Smith } PC_Galerkin; 152a6744ebSBarry Smith 16d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_Galerkin(PC pc, Vec x, Vec y) 17d71ae5a4SJacob Faibussowitsch { 182a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 192a6744ebSBarry Smith 202a6744ebSBarry Smith PetscFunctionBegin; 212fa5cd67SKarl Rupp if (jac->R) { 229566063dSJacob Faibussowitsch PetscCall(MatRestrict(jac->R, x, jac->b)); 232fa5cd67SKarl Rupp } else { 249566063dSJacob Faibussowitsch PetscCall(MatRestrict(jac->P, x, jac->b)); 252fa5cd67SKarl Rupp } 269566063dSJacob Faibussowitsch PetscCall(KSPSolve(jac->ksp, jac->b, jac->x)); 279566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(jac->ksp, pc, jac->x)); 282fa5cd67SKarl Rupp if (jac->P) { 299566063dSJacob Faibussowitsch PetscCall(MatInterpolate(jac->P, jac->x, y)); 302fa5cd67SKarl Rupp } else { 319566063dSJacob Faibussowitsch PetscCall(MatInterpolate(jac->R, jac->x, y)); 322fa5cd67SKarl Rupp } 333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 342a6744ebSBarry Smith } 352a6744ebSBarry Smith 36d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_Galerkin(PC pc) 37d71ae5a4SJacob Faibussowitsch { 382a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 39ace3abfcSBarry Smith PetscBool a; 40906ed7ccSBarry Smith Vec *xx, *yy; 412a6744ebSBarry Smith 422a6744ebSBarry Smith PetscFunctionBegin; 43b3402f20SBarry Smith if (jac->computeasub) { 44b3402f20SBarry Smith Mat Ap; 45b3402f20SBarry Smith if (!pc->setupcalled) { 469566063dSJacob Faibussowitsch PetscCall((*jac->computeasub)(pc, pc->pmat, NULL, &Ap, jac->computeasub_ctx)); 479566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(jac->ksp, Ap, Ap)); 489566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Ap)); 49b3402f20SBarry Smith } else { 509566063dSJacob Faibussowitsch PetscCall(KSPGetOperators(jac->ksp, NULL, &Ap)); 519566063dSJacob Faibussowitsch PetscCall((*jac->computeasub)(pc, pc->pmat, Ap, NULL, jac->computeasub_ctx)); 52b3402f20SBarry Smith } 53b3402f20SBarry Smith } 54b3402f20SBarry Smith 552a6744ebSBarry Smith if (!jac->x) { 569566063dSJacob Faibussowitsch PetscCall(KSPGetOperatorsSet(jac->ksp, &a, NULL)); 5728b400f6SJacob Faibussowitsch PetscCheck(a, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set operator of PCGALERKIN KSP with PCGalerkinGetKSP()/KSPSetOperators()"); 589566063dSJacob Faibussowitsch PetscCall(KSPCreateVecs(jac->ksp, 1, &xx, 1, &yy)); 59906ed7ccSBarry Smith jac->x = *xx; 60906ed7ccSBarry Smith jac->b = *yy; 619566063dSJacob Faibussowitsch PetscCall(PetscFree(xx)); 629566063dSJacob Faibussowitsch PetscCall(PetscFree(yy)); 632a6744ebSBarry Smith } 647827d75bSBarry Smith PetscCheck(jac->R || jac->P, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONGSTATE, "Must set restriction or interpolation of PCGALERKIN with PCGalerkinSetRestriction()/Interpolation()"); 652a6744ebSBarry Smith /* should check here that sizes of R/P match size of a */ 66b3402f20SBarry Smith 673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 682a6744ebSBarry Smith } 692a6744ebSBarry Smith 70d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_Galerkin(PC pc) 71d71ae5a4SJacob Faibussowitsch { 722a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 732a6744ebSBarry Smith 742a6744ebSBarry Smith PetscFunctionBegin; 759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->R)); 769566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->P)); 779566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->x)); 789566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->b)); 799566063dSJacob Faibussowitsch PetscCall(KSPReset(jac->ksp)); 803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81a06653b4SBarry Smith } 82a06653b4SBarry Smith 83d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_Galerkin(PC pc) 84d71ae5a4SJacob Faibussowitsch { 85a06653b4SBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 86a06653b4SBarry Smith 87a06653b4SBarry Smith PetscFunctionBegin; 889566063dSJacob Faibussowitsch PetscCall(PCReset_Galerkin(pc)); 899566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&jac->ksp)); 909566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 922a6744ebSBarry Smith } 932a6744ebSBarry Smith 94d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_Galerkin(PC pc, PetscViewer viewer) 95d71ae5a4SJacob Faibussowitsch { 962a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 97ace3abfcSBarry Smith PetscBool iascii; 982a6744ebSBarry Smith 992a6744ebSBarry Smith PetscFunctionBegin; 1009566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1012a6744ebSBarry Smith if (iascii) { 1029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " KSP on Galerkin follow\n")); 1039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------------------------------\n")); 1042a6744ebSBarry Smith } 1059566063dSJacob Faibussowitsch PetscCall(KSPView(jac->ksp, viewer)); 1063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1072a6744ebSBarry Smith } 1082a6744ebSBarry Smith 109d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGalerkinGetKSP_Galerkin(PC pc, KSP *ksp) 110d71ae5a4SJacob Faibussowitsch { 1112a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 1122a6744ebSBarry Smith 1132a6744ebSBarry Smith PetscFunctionBegin; 1142a6744ebSBarry Smith *ksp = jac->ksp; 1153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1162a6744ebSBarry Smith } 1172a6744ebSBarry Smith 118d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGalerkinSetRestriction_Galerkin(PC pc, Mat R) 119d71ae5a4SJacob Faibussowitsch { 1202a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 1212a6744ebSBarry Smith 1222a6744ebSBarry Smith PetscFunctionBegin; 1239566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)R)); 1249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->R)); 1252a6744ebSBarry Smith jac->R = R; 1263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1272a6744ebSBarry Smith } 1282a6744ebSBarry Smith 129d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGalerkinSetInterpolation_Galerkin(PC pc, Mat P) 130d71ae5a4SJacob Faibussowitsch { 1312a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 1322a6744ebSBarry Smith 1332a6744ebSBarry Smith PetscFunctionBegin; 1349566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)P)); 1359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->P)); 1362a6744ebSBarry Smith jac->P = P; 1373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1382a6744ebSBarry Smith } 1392a6744ebSBarry Smith 140d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGalerkinSetComputeSubmatrix_Galerkin(PC pc, PetscErrorCode (*computeAsub)(PC, Mat, Mat, Mat *, void *), void *ctx) 141d71ae5a4SJacob Faibussowitsch { 142b3402f20SBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 143b3402f20SBarry Smith 144b3402f20SBarry Smith PetscFunctionBegin; 145b3402f20SBarry Smith jac->computeasub = computeAsub; 146b3402f20SBarry Smith jac->computeasub_ctx = ctx; 1473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 148b3402f20SBarry Smith } 149b3402f20SBarry Smith 1502a6744ebSBarry Smith /*@ 151f1580f4eSBarry Smith PCGalerkinSetRestriction - Sets the restriction operator for the `PCGALERKIN` preconditioner 1522a6744ebSBarry Smith 153c3339decSBarry Smith Logically Collective 1542a6744ebSBarry Smith 155d8d19677SJose E. Roman Input Parameters: 1562a6744ebSBarry Smith + pc - the preconditioner context 1572a6744ebSBarry Smith - R - the restriction operator 1582a6744ebSBarry Smith 159feefa0e1SJacob Faibussowitsch Level: intermediate 16020f4b53cSBarry Smith 161f1580f4eSBarry Smith Note: 162f1580f4eSBarry Smith Either this or `PCGalerkinSetInterpolation()` or both must be called 1632a6744ebSBarry Smith 16420f4b53cSBarry Smith .seealso: `PC`, `PCCreate()`, `PCSetType()`, `PCType`, `PCGALERKIN`, 165db781477SPatrick Sanan `PCGalerkinSetInterpolation()`, `PCGalerkinGetKSP()` 1662a6744ebSBarry Smith @*/ 167d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGalerkinSetRestriction(PC pc, Mat R) 168d71ae5a4SJacob Faibussowitsch { 1692a6744ebSBarry Smith PetscFunctionBegin; 1700700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 171cac4c232SBarry Smith PetscTryMethod(pc, "PCGalerkinSetRestriction_C", (PC, Mat), (pc, R)); 1723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1732a6744ebSBarry Smith } 1742a6744ebSBarry Smith 1752a6744ebSBarry Smith /*@ 176f1580f4eSBarry Smith PCGalerkinSetInterpolation - Sets the interpolation operator for the `PCGALERKIN` preconditioner 1772a6744ebSBarry Smith 178c3339decSBarry Smith Logically Collective 1792a6744ebSBarry Smith 180d8d19677SJose E. Roman Input Parameters: 1812a6744ebSBarry Smith + pc - the preconditioner context 182feefa0e1SJacob Faibussowitsch - P - the interpolation operator 1832a6744ebSBarry Smith 184feefa0e1SJacob Faibussowitsch Level: intermediate 18520f4b53cSBarry Smith 186f1580f4eSBarry Smith Note: 187f1580f4eSBarry Smith Either this or `PCGalerkinSetRestriction()` or both must be called 1882a6744ebSBarry Smith 18920f4b53cSBarry Smith .seealso: `PC`, `PCCreate()`, `PCSetType()`, `PCType`, `PCGALERKIN`, 190db781477SPatrick Sanan `PCGalerkinSetRestriction()`, `PCGalerkinGetKSP()` 1912a6744ebSBarry Smith @*/ 192d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGalerkinSetInterpolation(PC pc, Mat P) 193d71ae5a4SJacob Faibussowitsch { 1942a6744ebSBarry Smith PetscFunctionBegin; 1950700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 196cac4c232SBarry Smith PetscTryMethod(pc, "PCGalerkinSetInterpolation_C", (PC, Mat), (pc, P)); 1973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1982a6744ebSBarry Smith } 1992a6744ebSBarry Smith 200feefa0e1SJacob Faibussowitsch /*@C 201b3402f20SBarry Smith PCGalerkinSetComputeSubmatrix - Provide a routine that will be called to compute the Galerkin submatrix 202b3402f20SBarry Smith 203b3402f20SBarry Smith Logically Collective 204b3402f20SBarry Smith 205d8d19677SJose E. Roman Input Parameters: 206b3402f20SBarry Smith + pc - the preconditioner context 207b3402f20SBarry Smith . computeAsub - routine that computes the submatrix from the global matrix 20820f4b53cSBarry Smith - ctx - context used by the routine, or `NULL` 209b3402f20SBarry Smith 21020f4b53cSBarry Smith Calling sequence of `computeAsub`: 211*04c3f3b8SBarry Smith + pc - the `PCGALERKIN` preconditioner 212f1580f4eSBarry Smith . A - the matrix in the `PCGALERKIN` 21320f4b53cSBarry Smith . Ap - the computed submatrix from any previous computation, if `NULL` it has not previously been computed 214b3402f20SBarry Smith . cAp - the submatrix computed by this routine 215b3402f20SBarry Smith - ctx - optional user-defined function context 216b3402f20SBarry Smith 217feefa0e1SJacob Faibussowitsch Level: intermediate 218b3402f20SBarry Smith 21995452b02SPatrick Sanan Notes: 220f1580f4eSBarry Smith Instead of providing this routine you can call `PCGalerkinGetKSP()` and then `KSPSetOperators()` to provide the submatrix, 221f1580f4eSBarry Smith but that will not work for multiple `KSPSolve()`s with different matrices unless you call it for each solve. 222b3402f20SBarry Smith 22320f4b53cSBarry Smith This routine is called each time the outer matrix is changed. In the first call the Ap argument is `NULL` and the routine should create the 224b3402f20SBarry Smith matrix and computes its values in cAp. On each subsequent call the routine should up the Ap matrix. 225b3402f20SBarry Smith 226feefa0e1SJacob Faibussowitsch Developer Notes: 227f1580f4eSBarry Smith If the user does not call this routine nor call `PCGalerkinGetKSP()` and `KSPSetOperators()` then `PCGALERKIN` 228f1580f4eSBarry Smith could automatically compute the submatrix via calls to `MatGalerkin()` or `MatRARt()` 229b3402f20SBarry Smith 23020f4b53cSBarry Smith .seealso: `PC`, `PCCreate()`, `PCSetType()`, `PCType`, `PCGALERKIN`, 231db781477SPatrick Sanan `PCGalerkinSetRestriction()`, `PCGalerkinSetInterpolation()`, `PCGalerkinGetKSP()` 232b3402f20SBarry Smith @*/ 233*04c3f3b8SBarry Smith PetscErrorCode PCGalerkinSetComputeSubmatrix(PC pc, PetscErrorCode (*computeAsub)(PC pc, Mat A, Mat Ap, Mat *cAp, void *ctx), void *ctx) 234d71ae5a4SJacob Faibussowitsch { 235b3402f20SBarry Smith PetscFunctionBegin; 236b3402f20SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 237cac4c232SBarry Smith PetscTryMethod(pc, "PCGalerkinSetComputeSubmatrix_C", (PC, PetscErrorCode(*)(PC, Mat, Mat, Mat *, void *), void *), (pc, computeAsub, ctx)); 2383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 239b3402f20SBarry Smith } 240b3402f20SBarry Smith 241b3402f20SBarry Smith /*@ 242f1580f4eSBarry Smith PCGalerkinGetKSP - Gets the `KSP` object in the `PCGALERKIN` 2432a6744ebSBarry Smith 2442a6744ebSBarry Smith Not Collective 2452a6744ebSBarry Smith 2462a6744ebSBarry Smith Input Parameter: 2472a6744ebSBarry Smith . pc - the preconditioner context 2482a6744ebSBarry Smith 249f1580f4eSBarry Smith Output Parameter: 250f1580f4eSBarry Smith . ksp - the `KSP` object 2512a6744ebSBarry Smith 252feefa0e1SJacob Faibussowitsch Level: intermediate 2532a6744ebSBarry Smith 254f1580f4eSBarry Smith Note: 255*04c3f3b8SBarry Smith Once you have called this routine you can call `KSPSetOperators()` on the resulting `KSP` to provide the operator for the Galerkin problem, 256f1580f4eSBarry Smith an alternative is to use `PCGalerkinSetComputeSubmatrix()` to provide a routine that computes the submatrix as needed. 257b3402f20SBarry Smith 25820f4b53cSBarry Smith .seealso: `PC`, `PCCreate()`, `PCSetType()`, `PCType`, `PCGALERKIN`, 259db781477SPatrick Sanan `PCGalerkinSetRestriction()`, `PCGalerkinSetInterpolation()`, `PCGalerkinSetComputeSubmatrix()` 2602a6744ebSBarry Smith @*/ 261d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGalerkinGetKSP(PC pc, KSP *ksp) 262d71ae5a4SJacob Faibussowitsch { 2632a6744ebSBarry Smith PetscFunctionBegin; 2640700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2654f572ea9SToby Isaac PetscAssertPointer(ksp, 2); 266cac4c232SBarry Smith PetscUseMethod(pc, "PCGalerkinGetKSP_C", (PC, KSP *), (pc, ksp)); 2673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2682a6744ebSBarry Smith } 2692a6744ebSBarry Smith 270d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_Galerkin(PC pc, PetscOptionItems *PetscOptionsObject) 271d71ae5a4SJacob Faibussowitsch { 2724ac220ccSBarry Smith PC_Galerkin *jac = (PC_Galerkin *)pc->data; 2734ac220ccSBarry Smith const char *prefix; 2744ac220ccSBarry Smith PetscBool flg; 2754ac220ccSBarry Smith 2764ac220ccSBarry Smith PetscFunctionBegin; 2779566063dSJacob Faibussowitsch PetscCall(KSPGetOptionsPrefix(jac->ksp, &prefix)); 2789566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(prefix, "galerkin_", &flg)); 2794ac220ccSBarry Smith if (!flg) { 2809566063dSJacob Faibussowitsch PetscCall(PCGetOptionsPrefix(pc, &prefix)); 2819566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(jac->ksp, prefix)); 2829566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(jac->ksp, "galerkin_")); 2834ac220ccSBarry Smith } 2844ac220ccSBarry Smith 285d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "Galerkin options"); 2861baa6e33SBarry Smith if (jac->ksp) PetscCall(KSPSetFromOptions(jac->ksp)); 287d0609cedSBarry Smith PetscOptionsHeadEnd(); 2883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2894ac220ccSBarry Smith } 2902a6744ebSBarry Smith 2912a6744ebSBarry Smith /*MC 2922a6744ebSBarry Smith PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T) 2932a6744ebSBarry Smith 2942a6744ebSBarry Smith Level: intermediate 2952a6744ebSBarry Smith 29620f4b53cSBarry Smith Note: 29720f4b53cSBarry Smith Use 29820f4b53cSBarry Smith .vb 29920f4b53cSBarry Smith `PCGalerkinSetRestriction`(pc,R) and/or `PCGalerkinSetInterpolation`(pc,P) 30020f4b53cSBarry Smith `PCGalerkinGetKSP`(pc,&ksp); 30120f4b53cSBarry Smith `KSPSetOperators`(ksp,A,....) 30220f4b53cSBarry Smith ... 30320f4b53cSBarry Smith .ve 30420f4b53cSBarry Smith 305f1580f4eSBarry Smith Developer Notes: 306f1580f4eSBarry Smith If `KSPSetOperators()` has not been called on the inner `KSP` then `PCGALERKIN` could use `MatRARt()` or `MatPtAP()` to compute 3077817a140SBarry Smith the operators automatically. 308f1580f4eSBarry Smith 309f1580f4eSBarry Smith Should there be a prefix for the inner `KSP`? 310f1580f4eSBarry Smith 311f1580f4eSBarry Smith There is no `KSPSetFromOptions_Galerkin()` that calls `KSPSetFromOptions()` on the inner `KSP` 3127817a140SBarry Smith 313db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, 314db781477SPatrick Sanan `PCSHELL`, `PCKSP`, `PCGalerkinSetRestriction()`, `PCGalerkinSetInterpolation()`, `PCGalerkinGetKSP()` 3152a6744ebSBarry Smith M*/ 3162a6744ebSBarry Smith 317d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc) 318d71ae5a4SJacob Faibussowitsch { 3192a6744ebSBarry Smith PC_Galerkin *jac; 3202a6744ebSBarry Smith 3212a6744ebSBarry Smith PetscFunctionBegin; 3224dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac)); 3232fa5cd67SKarl Rupp 3242a6744ebSBarry Smith pc->ops->apply = PCApply_Galerkin; 3252a6744ebSBarry Smith pc->ops->setup = PCSetUp_Galerkin; 326a06653b4SBarry Smith pc->ops->reset = PCReset_Galerkin; 3272a6744ebSBarry Smith pc->ops->destroy = PCDestroy_Galerkin; 3282a6744ebSBarry Smith pc->ops->view = PCView_Galerkin; 3294ac220ccSBarry Smith pc->ops->setfromoptions = PCSetFromOptions_Galerkin; 3304ac220ccSBarry Smith pc->ops->applyrichardson = NULL; 3312a6744ebSBarry Smith 3329566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)pc), &jac->ksp)); 3333821be0aSBarry Smith PetscCall(KSPSetNestLevel(jac->ksp, pc->kspnestlevel)); 3349566063dSJacob Faibussowitsch PetscCall(KSPSetErrorIfNotConverged(jac->ksp, pc->erroriffailure)); 3359566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)jac->ksp, (PetscObject)pc, 1)); 3362a6744ebSBarry Smith 3372a6744ebSBarry Smith pc->data = (void *)jac; 3382a6744ebSBarry Smith 3399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGalerkinSetRestriction_C", PCGalerkinSetRestriction_Galerkin)); 3409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGalerkinSetInterpolation_C", PCGalerkinSetInterpolation_Galerkin)); 3419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGalerkinGetKSP_C", PCGalerkinGetKSP_Galerkin)); 3429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGalerkinSetComputeSubmatrix_C", PCGalerkinSetComputeSubmatrix_Galerkin)); 3433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3442a6744ebSBarry Smith } 345