Actual source code: shellpc.c
1: /*
2: This provides a simple shell for Fortran (and C programmers) to
3: create their own preconditioner without writing much interface code.
4: */
6: #include <petsc/private/pcimpl.h>
8: typedef struct {
9: PetscCtx ctx; /* user provided contexts for preconditioner */
11: PetscErrorCode (*destroy)(PC);
12: PetscErrorCode (*setup)(PC);
13: PetscErrorCode (*apply)(PC, Vec, Vec);
14: PetscErrorCode (*matapply)(PC, Mat, Mat);
15: PetscErrorCode (*applysymmetricleft)(PC, Vec, Vec);
16: PetscErrorCode (*applysymmetricright)(PC, Vec, Vec);
17: PetscErrorCode (*applyBA)(PC, PCSide, Vec, Vec, Vec);
18: PetscErrorCode (*presolve)(PC, KSP, Vec, Vec);
19: PetscErrorCode (*postsolve)(PC, KSP, Vec, Vec);
20: PetscErrorCode (*view)(PC, PetscViewer);
21: PetscErrorCode (*applytranspose)(PC, Vec, Vec);
22: PetscErrorCode (*matapplytranspose)(PC, Mat, Mat);
23: PetscErrorCode (*applyrich)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *);
24: PetscErrorCode (*matapplyrich)(PC, Mat, Mat, Mat, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *);
26: char *name;
27: } PC_Shell;
29: /*@
30: PCShellGetContext - Returns the user-provided context associated with a shell `PC` that was provided with `PCShellSetContext()`
32: Not Collective
34: Input Parameter:
35: . pc - of type `PCSHELL`
37: Output Parameter:
38: . ctx - the user provided context
40: Level: advanced
42: Note:
43: This routine is intended for use within the various user-provided routines set with, for example, `PCShellSetApply()`
45: Fortran Notes:
46: This only works when the context is a Fortran derived type or a `PetscObject`. Define `ctx` with
47: .vb
48: type(tUsertype), pointer :: ctx
49: .ve
51: .seealso: [](ch_ksp), `PC`, `PCSHELL`, `PCShellSetContext()`, `PCShellSetApply()`, `PCShellSetDestroy()`
52: @*/
53: PetscErrorCode PCShellGetContext(PC pc, PetscCtxRt ctx)
54: {
55: PetscBool flg;
57: PetscFunctionBegin;
59: PetscAssertPointer(ctx, 2);
60: PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCSHELL, &flg));
61: if (!flg) *(void **)ctx = NULL;
62: else *(void **)ctx = ((PC_Shell *)pc->data)->ctx;
63: PetscFunctionReturn(PETSC_SUCCESS);
64: }
66: /*@
67: PCShellSetContext - sets the context for a shell `PC` that can be accessed with `PCShellGetContext()`
69: Logically Collective
71: Input Parameters:
72: + pc - the `PC` of type `PCSHELL`
73: - ctx - the context
75: Level: advanced
77: Notes:
78: This routine is intended for use within the various user-provided routines set with, for example, `PCShellSetApply()`
80: One should also provide a routine to destroy the context when `pc` is destroyed with `PCShellSetDestroy()`
82: Fortran Notes:
83: To use this from Fortran you must write a Fortran interface definition for this
84: function that tells Fortran the Fortran derived data type that you are passing in as the `ctx` argument.
86: .seealso: [](ch_ksp), `PC`, `PCShellGetContext()`, `PCSHELL`, `PCShellSetApply()`, `PCShellSetDestroy()`
87: @*/
88: PetscErrorCode PCShellSetContext(PC pc, PetscCtx ctx)
89: {
90: PC_Shell *shell = (PC_Shell *)pc->data;
91: PetscBool flg;
93: PetscFunctionBegin;
95: PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCSHELL, &flg));
96: if (flg) shell->ctx = ctx;
97: PetscFunctionReturn(PETSC_SUCCESS);
98: }
100: static PetscErrorCode PCSetUp_Shell(PC pc)
101: {
102: PC_Shell *shell = (PC_Shell *)pc->data;
104: PetscFunctionBegin;
105: PetscCheck(shell->setup, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No setup() routine provided to Shell PC");
106: PetscCallBack("PCSHELL callback setup", (*shell->setup)(pc));
107: PetscFunctionReturn(PETSC_SUCCESS);
108: }
110: static PetscErrorCode PCApply_Shell(PC pc, Vec x, Vec y)
111: {
112: PC_Shell *shell = (PC_Shell *)pc->data;
113: PetscObjectState instate, outstate;
115: PetscFunctionBegin;
116: PetscCheck(shell->apply, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
117: PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
118: PetscCallBack("PCSHELL callback apply", (*shell->apply)(pc, x, y));
119: PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
120: /* increase the state of the output vector if the user did not update its state themself as should have been done */
121: if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
122: PetscFunctionReturn(PETSC_SUCCESS);
123: }
125: static PetscErrorCode PCMatApply_Shell(PC pc, Mat X, Mat Y)
126: {
127: PC_Shell *shell = (PC_Shell *)pc->data;
128: PetscObjectState instate, outstate;
130: PetscFunctionBegin;
131: PetscCheck(shell->matapply, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
132: PetscCall(PetscObjectStateGet((PetscObject)Y, &instate));
133: PetscCallBack("PCSHELL callback apply", (*shell->matapply)(pc, X, Y));
134: PetscCall(PetscObjectStateGet((PetscObject)Y, &outstate));
135: /* increase the state of the output vector if the user did not update its state themself as should have been done */
136: if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)Y));
137: PetscFunctionReturn(PETSC_SUCCESS);
138: }
140: static PetscErrorCode PCApplySymmetricLeft_Shell(PC pc, Vec x, Vec y)
141: {
142: PC_Shell *shell = (PC_Shell *)pc->data;
144: PetscFunctionBegin;
145: PetscCheck(shell->applysymmetricleft, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
146: PetscCallBack("PCSHELL callback apply symmetric left", (*shell->applysymmetricleft)(pc, x, y));
147: PetscFunctionReturn(PETSC_SUCCESS);
148: }
150: static PetscErrorCode PCApplySymmetricRight_Shell(PC pc, Vec x, Vec y)
151: {
152: PC_Shell *shell = (PC_Shell *)pc->data;
154: PetscFunctionBegin;
155: PetscCheck(shell->applysymmetricright, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
156: PetscCallBack("PCSHELL callback apply symmetric right", (*shell->applysymmetricright)(pc, x, y));
157: PetscFunctionReturn(PETSC_SUCCESS);
158: }
160: static PetscErrorCode PCApplyBA_Shell(PC pc, PCSide side, Vec x, Vec y, Vec w)
161: {
162: PC_Shell *shell = (PC_Shell *)pc->data;
163: PetscObjectState instate, outstate;
165: PetscFunctionBegin;
166: PetscCheck(shell->applyBA, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applyBA() routine provided to Shell PC");
167: PetscCall(PetscObjectStateGet((PetscObject)w, &instate));
168: PetscCallBack("PCSHELL callback applyBA", (*shell->applyBA)(pc, side, x, y, w));
169: PetscCall(PetscObjectStateGet((PetscObject)w, &outstate));
170: /* increase the state of the output vector if the user did not update its state themself as should have been done */
171: if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)w));
172: PetscFunctionReturn(PETSC_SUCCESS);
173: }
175: static PetscErrorCode PCPreSolveChangeRHS_Shell(PC pc, PetscBool *change)
176: {
177: PetscFunctionBegin;
178: *change = PETSC_TRUE;
179: PetscFunctionReturn(PETSC_SUCCESS);
180: }
182: static PetscErrorCode PCPreSolve_Shell(PC pc, KSP ksp, Vec b, Vec x)
183: {
184: PC_Shell *shell = (PC_Shell *)pc->data;
186: PetscFunctionBegin;
187: PetscCheck(shell->presolve, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No presolve() routine provided to Shell PC");
188: PetscCallBack("PCSHELL callback presolve", (*shell->presolve)(pc, ksp, b, x));
189: PetscFunctionReturn(PETSC_SUCCESS);
190: }
192: static PetscErrorCode PCPostSolve_Shell(PC pc, KSP ksp, Vec b, Vec x)
193: {
194: PC_Shell *shell = (PC_Shell *)pc->data;
196: PetscFunctionBegin;
197: PetscCheck(shell->postsolve, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No postsolve() routine provided to Shell PC");
198: PetscCallBack("PCSHELL callback postsolve()", (*shell->postsolve)(pc, ksp, b, x));
199: PetscFunctionReturn(PETSC_SUCCESS);
200: }
202: static PetscErrorCode PCApplyTranspose_Shell(PC pc, Vec x, Vec y)
203: {
204: PC_Shell *shell = (PC_Shell *)pc->data;
205: PetscObjectState instate, outstate;
207: PetscFunctionBegin;
208: PetscCheck(shell->applytranspose, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applytranspose() routine provided to Shell PC");
209: PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
210: PetscCallBack("PCSHELL callback applytranspose", (*shell->applytranspose)(pc, x, y));
211: PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
212: /* increase the state of the output vector if the user did not update its state themself as should have been done */
213: if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
214: PetscFunctionReturn(PETSC_SUCCESS);
215: }
217: static PetscErrorCode PCMatApplyTranspose_Shell(PC pc, Mat x, Mat y)
218: {
219: PC_Shell *shell = (PC_Shell *)pc->data;
220: PetscObjectState instate, outstate;
222: PetscFunctionBegin;
223: PetscCheck(shell->matapplytranspose, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No matapplytranspose() routine provided to Shell PC");
224: PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
225: PetscCallBack("PCSHELL callback matapplytranspose", (*shell->matapplytranspose)(pc, x, y));
226: PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
227: /* increase the state of the output matrix if the user did not update its state themself as should have been done */
228: if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
229: PetscFunctionReturn(PETSC_SUCCESS);
230: }
232: static PetscErrorCode PCApplyRichardson_Shell(PC pc, Vec x, Vec y, Vec w, PetscReal rtol, PetscReal abstol, PetscReal dtol, PetscInt it, PetscBool guesszero, PetscInt *outits, PCRichardsonConvergedReason *reason)
233: {
234: PC_Shell *shell = (PC_Shell *)pc->data;
235: PetscObjectState instate, outstate;
237: PetscFunctionBegin;
238: PetscCheck(shell->applyrich, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applyrichardson() routine provided to Shell PC");
239: PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
240: PetscCallBack("PCSHELL callback applyrichardson", (*shell->applyrich)(pc, x, y, w, rtol, abstol, dtol, it, guesszero, outits, reason));
241: PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
242: /* increase the state of the output vector since the user did not update its state themself as should have been done */
243: if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
244: PetscFunctionReturn(PETSC_SUCCESS);
245: }
247: static PetscErrorCode PCMatApplyRichardson_Shell(PC pc, Mat B, Mat Y, Mat W, PetscReal rtol, PetscReal abstol, PetscReal dtol, PetscInt it, PetscBool guesszero, PetscInt *outits, PCRichardsonConvergedReason *reason)
248: {
249: PC_Shell *shell = (PC_Shell *)pc->data;
250: PetscObjectState instate, outstate;
252: PetscFunctionBegin;
253: PetscCheck(shell->matapplyrich, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No matapplyrichardson() routine provided to Shell PC");
254: PetscCall(PetscObjectStateGet((PetscObject)Y, &instate));
255: PetscCallBack("PCSHELL callback matapplyrichardson", (*shell->matapplyrich)(pc, B, Y, W, rtol, abstol, dtol, it, guesszero, outits, reason));
256: PetscCall(PetscObjectStateGet((PetscObject)Y, &outstate));
257: /* increase the state of the output block of vectors since the user did not update its state themself as should have been done */
258: if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)Y));
259: PetscFunctionReturn(PETSC_SUCCESS);
260: }
262: static PetscErrorCode PCDestroy_Shell(PC pc)
263: {
264: PC_Shell *shell = (PC_Shell *)pc->data;
266: PetscFunctionBegin;
267: PetscCall(PetscFree(shell->name));
268: if (shell->destroy) PetscCallBack("PCSHELL callback destroy", (*shell->destroy)(pc));
269: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetDestroy_C", NULL));
270: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetSetUp_C", NULL));
271: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApply_C", NULL));
272: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApply_C", NULL));
273: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricLeft_C", NULL));
274: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricRight_C", NULL));
275: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyBA_C", NULL));
276: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPreSolve_C", NULL));
277: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPostSolve_C", NULL));
278: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetView_C", NULL));
279: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyTranspose_C", NULL));
280: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApplyTranspose_C", NULL));
281: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetName_C", NULL));
282: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellGetName_C", NULL));
283: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyRichardson_C", NULL));
284: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApplyRichardson_C", NULL));
285: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", NULL));
286: PetscCall(PetscFree(pc->data));
287: PetscFunctionReturn(PETSC_SUCCESS);
288: }
290: static PetscErrorCode PCView_Shell(PC pc, PetscViewer viewer)
291: {
292: PC_Shell *shell = (PC_Shell *)pc->data;
293: PetscBool isascii;
295: PetscFunctionBegin;
296: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
297: if (isascii) {
298: if (shell->name) PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", shell->name));
299: else PetscCall(PetscViewerASCIIPrintf(viewer, " no name\n"));
300: }
301: if (shell->view) {
302: PetscCall(PetscViewerASCIIPushTab(viewer));
303: PetscCall((*shell->view)(pc, viewer));
304: PetscCall(PetscViewerASCIIPopTab(viewer));
305: }
306: PetscFunctionReturn(PETSC_SUCCESS);
307: }
309: static PetscErrorCode PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(PC))
310: {
311: PC_Shell *shell = (PC_Shell *)pc->data;
313: PetscFunctionBegin;
314: shell->destroy = destroy;
315: PetscFunctionReturn(PETSC_SUCCESS);
316: }
318: static PetscErrorCode PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(PC))
319: {
320: PC_Shell *shell = (PC_Shell *)pc->data;
322: PetscFunctionBegin;
323: shell->setup = setup;
324: if (setup) pc->ops->setup = PCSetUp_Shell;
325: else pc->ops->setup = NULL;
326: PetscFunctionReturn(PETSC_SUCCESS);
327: }
329: static PetscErrorCode PCShellSetApply_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec))
330: {
331: PC_Shell *shell = (PC_Shell *)pc->data;
333: PetscFunctionBegin;
334: shell->apply = apply;
335: PetscFunctionReturn(PETSC_SUCCESS);
336: }
338: static PetscErrorCode PCShellSetMatApply_Shell(PC pc, PetscErrorCode (*matapply)(PC, Mat, Mat))
339: {
340: PC_Shell *shell = (PC_Shell *)pc->data;
342: PetscFunctionBegin;
343: shell->matapply = matapply;
344: if (matapply) pc->ops->matapply = PCMatApply_Shell;
345: else pc->ops->matapply = NULL;
346: PetscFunctionReturn(PETSC_SUCCESS);
347: }
349: static PetscErrorCode PCShellSetApplySymmetricLeft_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec))
350: {
351: PC_Shell *shell = (PC_Shell *)pc->data;
353: PetscFunctionBegin;
354: shell->applysymmetricleft = apply;
355: PetscFunctionReturn(PETSC_SUCCESS);
356: }
358: static PetscErrorCode PCShellSetApplySymmetricRight_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec))
359: {
360: PC_Shell *shell = (PC_Shell *)pc->data;
362: PetscFunctionBegin;
363: shell->applysymmetricright = apply;
364: PetscFunctionReturn(PETSC_SUCCESS);
365: }
367: static PetscErrorCode PCShellSetApplyBA_Shell(PC pc, PetscErrorCode (*applyBA)(PC, PCSide, Vec, Vec, Vec))
368: {
369: PC_Shell *shell = (PC_Shell *)pc->data;
371: PetscFunctionBegin;
372: shell->applyBA = applyBA;
373: if (applyBA) pc->ops->applyBA = PCApplyBA_Shell;
374: else pc->ops->applyBA = NULL;
375: PetscFunctionReturn(PETSC_SUCCESS);
376: }
378: static PetscErrorCode PCShellSetPreSolve_Shell(PC pc, PCShellPSolveFn *presolve)
379: {
380: PC_Shell *shell = (PC_Shell *)pc->data;
382: PetscFunctionBegin;
383: shell->presolve = presolve;
384: if (presolve) {
385: pc->ops->presolve = PCPreSolve_Shell;
386: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", PCPreSolveChangeRHS_Shell));
387: } else {
388: pc->ops->presolve = NULL;
389: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", NULL));
390: }
391: PetscFunctionReturn(PETSC_SUCCESS);
392: }
394: static PetscErrorCode PCShellSetPostSolve_Shell(PC pc, PCShellPSolveFn *postsolve)
395: {
396: PC_Shell *shell = (PC_Shell *)pc->data;
398: PetscFunctionBegin;
399: shell->postsolve = postsolve;
400: if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
401: else pc->ops->postsolve = NULL;
402: PetscFunctionReturn(PETSC_SUCCESS);
403: }
405: static PetscErrorCode PCShellSetView_Shell(PC pc, PetscErrorCode (*view)(PC, PetscViewer))
406: {
407: PC_Shell *shell = (PC_Shell *)pc->data;
409: PetscFunctionBegin;
410: shell->view = view;
411: PetscFunctionReturn(PETSC_SUCCESS);
412: }
414: static PetscErrorCode PCShellSetApplyTranspose_Shell(PC pc, PetscErrorCode (*applytranspose)(PC, Vec, Vec))
415: {
416: PC_Shell *shell = (PC_Shell *)pc->data;
418: PetscFunctionBegin;
419: shell->applytranspose = applytranspose;
420: if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
421: else pc->ops->applytranspose = NULL;
422: PetscFunctionReturn(PETSC_SUCCESS);
423: }
425: static PetscErrorCode PCShellSetMatApplyTranspose_Shell(PC pc, PetscErrorCode (*matapplytranspose)(PC, Mat, Mat))
426: {
427: PC_Shell *shell = (PC_Shell *)pc->data;
429: PetscFunctionBegin;
430: shell->matapplytranspose = matapplytranspose;
431: if (matapplytranspose) pc->ops->matapplytranspose = PCMatApplyTranspose_Shell;
432: else pc->ops->matapplytranspose = NULL;
433: PetscFunctionReturn(PETSC_SUCCESS);
434: }
436: static PetscErrorCode PCShellSetApplyRichardson_Shell(PC pc, PetscErrorCode (*applyrich)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *))
437: {
438: PC_Shell *shell = (PC_Shell *)pc->data;
440: PetscFunctionBegin;
441: shell->applyrich = applyrich;
442: if (applyrich) pc->ops->applyrichardson = PCApplyRichardson_Shell;
443: else pc->ops->applyrichardson = NULL;
444: PetscFunctionReturn(PETSC_SUCCESS);
445: }
447: static PetscErrorCode PCShellSetMatApplyRichardson_Shell(PC pc, PetscErrorCode (*matapplyrich)(PC, Mat, Mat, Mat, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *))
448: {
449: PC_Shell *shell = (PC_Shell *)pc->data;
451: PetscFunctionBegin;
452: shell->matapplyrich = matapplyrich;
453: if (matapplyrich) pc->ops->matapplyrichardson = PCMatApplyRichardson_Shell;
454: else pc->ops->matapplyrichardson = NULL;
455: PetscFunctionReturn(PETSC_SUCCESS);
456: }
458: static PetscErrorCode PCShellSetName_Shell(PC pc, const char name[])
459: {
460: PC_Shell *shell = (PC_Shell *)pc->data;
462: PetscFunctionBegin;
463: PetscCall(PetscFree(shell->name));
464: PetscCall(PetscStrallocpy(name, &shell->name));
465: PetscFunctionReturn(PETSC_SUCCESS);
466: }
468: static PetscErrorCode PCShellGetName_Shell(PC pc, const char *name[])
469: {
470: PC_Shell *shell = (PC_Shell *)pc->data;
472: PetscFunctionBegin;
473: *name = shell->name;
474: PetscFunctionReturn(PETSC_SUCCESS);
475: }
477: /*@
478: PCShellSetDestroy - Sets routine to use to destroy the user-provided application context that was provided with `PCShellSetContext()`
480: Logically Collective
482: Input Parameters:
483: + pc - the preconditioner context
484: - destroy - the application-provided destroy routine
486: Calling sequence of `destroy`:
487: . pc - the preconditioner
489: Level: intermediate
491: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellGetContext()`
492: @*/
493: PetscErrorCode PCShellSetDestroy(PC pc, PetscErrorCode (*destroy)(PC pc))
494: {
495: PetscFunctionBegin;
497: PetscTryMethod(pc, "PCShellSetDestroy_C", (PC, PetscErrorCode (*)(PC)), (pc, destroy));
498: PetscFunctionReturn(PETSC_SUCCESS);
499: }
501: /*@
502: PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
503: matrix operator is changed.
505: Logically Collective
507: Input Parameters:
508: + pc - the preconditioner context
509: - setup - the application-provided setup routine
511: Calling sequence of `setup`:
512: . pc - the preconditioner
514: Level: intermediate
516: Note:
517: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `setup`.
519: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellGetContext()`
520: @*/
521: PetscErrorCode PCShellSetSetUp(PC pc, PetscErrorCode (*setup)(PC pc))
522: {
523: PetscFunctionBegin;
525: PetscTryMethod(pc, "PCShellSetSetUp_C", (PC, PetscErrorCode (*)(PC)), (pc, setup));
526: PetscFunctionReturn(PETSC_SUCCESS);
527: }
529: /*@
530: PCShellSetView - Sets routine to use as viewer of a `PCSHELL` shell preconditioner
532: Logically Collective
534: Input Parameters:
535: + pc - the preconditioner context
536: - view - the application-provided view routine
538: Calling sequence of `view`:
539: + pc - the preconditioner
540: - v - viewer
542: Level: advanced
544: Note:
545: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `view`.
547: .seealso: [](ch_ksp), `PC`, `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellGetContext()`
548: @*/
549: PetscErrorCode PCShellSetView(PC pc, PetscErrorCode (*view)(PC pc, PetscViewer v))
550: {
551: PetscFunctionBegin;
553: PetscTryMethod(pc, "PCShellSetView_C", (PC, PetscErrorCode (*)(PC, PetscViewer)), (pc, view));
554: PetscFunctionReturn(PETSC_SUCCESS);
555: }
557: /*@
558: PCShellSetApply - Sets routine to use as preconditioner.
560: Logically Collective
562: Input Parameters:
563: + pc - the preconditioner context
564: - apply - the application-provided preconditioning routine
566: Calling sequence of `apply`:
567: + pc - the preconditioner, get the application context with `PCShellGetContext()`
568: . xin - input vector
569: - xout - output vector
571: Level: intermediate
573: Note:
574: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `apply`.
576: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellSetApplyBA()`, `PCShellSetApplySymmetricRight()`, `PCShellSetApplySymmetricLeft()`, `PCShellGetContext()`
577: @*/
578: PetscErrorCode PCShellSetApply(PC pc, PetscErrorCode (*apply)(PC pc, Vec xin, Vec xout))
579: {
580: PetscFunctionBegin;
582: PetscTryMethod(pc, "PCShellSetApply_C", (PC, PetscErrorCode (*)(PC, Vec, Vec)), (pc, apply));
583: PetscFunctionReturn(PETSC_SUCCESS);
584: }
586: /*@
587: PCShellSetMatApply - Sets routine to use as preconditioner on a block of vectors.
589: Logically Collective
591: Input Parameters:
592: + pc - the preconditioner context
593: - matapply - the application-provided preconditioning routine
595: Calling sequence of `matapply`:
596: + pc - the preconditioner
597: . Xin - input block of vectors represented as a dense `Mat`
598: - Xout - output block of vectors represented as a dense `Mat`
600: Level: advanced
602: Note:
603: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `matapply`.
605: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellGetContext()`
606: @*/
607: PetscErrorCode PCShellSetMatApply(PC pc, PetscErrorCode (*matapply)(PC pc, Mat Xin, Mat Xout))
608: {
609: PetscFunctionBegin;
611: PetscTryMethod(pc, "PCShellSetMatApply_C", (PC, PetscErrorCode (*)(PC, Mat, Mat)), (pc, matapply));
612: PetscFunctionReturn(PETSC_SUCCESS);
613: }
615: /*@
616: PCShellSetApplySymmetricLeft - Sets routine to use as left preconditioner (when the `PC_SYMMETRIC` is used).
618: Logically Collective
620: Input Parameters:
621: + pc - the preconditioner context
622: - apply - the application-provided left preconditioning routine
624: Calling sequence of `apply`:
625: + pc - the preconditioner
626: . xin - input vector
627: - xout - output vector
629: Level: advanced
631: Note:
632: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `apply`.
634: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`
635: @*/
636: PetscErrorCode PCShellSetApplySymmetricLeft(PC pc, PetscErrorCode (*apply)(PC pc, Vec xin, Vec xout))
637: {
638: PetscFunctionBegin;
640: PetscTryMethod(pc, "PCShellSetApplySymmetricLeft_C", (PC, PetscErrorCode (*)(PC, Vec, Vec)), (pc, apply));
641: PetscFunctionReturn(PETSC_SUCCESS);
642: }
644: /*@
645: PCShellSetApplySymmetricRight - Sets routine to use as right preconditioner (when the `PC_SYMMETRIC` is used).
647: Logically Collective
649: Input Parameters:
650: + pc - the preconditioner context
651: - apply - the application-provided right preconditioning routine
653: Calling sequence of `apply`:
654: + pc - the preconditioner
655: . xin - input vector
656: - xout - output vector
658: Level: advanced
660: Note:
661: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `apply`.
663: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetApplySymmetricLeft()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellGetContext()`
664: @*/
665: PetscErrorCode PCShellSetApplySymmetricRight(PC pc, PetscErrorCode (*apply)(PC pc, Vec xin, Vec xout))
666: {
667: PetscFunctionBegin;
669: PetscTryMethod(pc, "PCShellSetApplySymmetricRight_C", (PC, PetscErrorCode (*)(PC, Vec, Vec)), (pc, apply));
670: PetscFunctionReturn(PETSC_SUCCESS);
671: }
673: /*@
674: PCShellSetApplyBA - Sets routine to use as the preconditioner times the operator.
676: Logically Collective
678: Input Parameters:
679: + pc - the preconditioner context
680: - applyBA - the application-provided BA routine
682: Calling sequence of `applyBA`:
683: + pc - the preconditioner
684: . side - `PC_LEFT`, `PC_RIGHT`, or `PC_SYMMETRIC`
685: . xin - input vector
686: . xout - output vector
687: - w - work vector
689: Level: intermediate
691: Note:
692: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `applyBA`.
694: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellSetApply()`, `PCShellGetContext()`, `PCSide`
695: @*/
696: PetscErrorCode PCShellSetApplyBA(PC pc, PetscErrorCode (*applyBA)(PC pc, PCSide side, Vec xin, Vec xout, Vec w))
697: {
698: PetscFunctionBegin;
700: PetscTryMethod(pc, "PCShellSetApplyBA_C", (PC, PetscErrorCode (*)(PC, PCSide, Vec, Vec, Vec)), (pc, applyBA));
701: PetscFunctionReturn(PETSC_SUCCESS);
702: }
704: /*@
705: PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
707: Logically Collective
709: Input Parameters:
710: + pc - the preconditioner context
711: - applytranspose - the application-provided preconditioning transpose routine
713: Calling sequence of `applytranspose`:
714: + pc - the preconditioner
715: . xin - input vector
716: - xout - output vector
718: Level: intermediate
720: Note:
721: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `applytranspose`.
723: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellSetApplyBA()`, `PCShellGetContext()`
724: @*/
725: PetscErrorCode PCShellSetApplyTranspose(PC pc, PetscErrorCode (*applytranspose)(PC pc, Vec xin, Vec xout))
726: {
727: PetscFunctionBegin;
729: PetscTryMethod(pc, "PCShellSetApplyTranspose_C", (PC, PetscErrorCode (*)(PC, Vec, Vec)), (pc, applytranspose));
730: PetscFunctionReturn(PETSC_SUCCESS);
731: }
733: /*@
734: PCShellSetMatApplyTranspose - Sets routine to use as preconditioner transpose.
736: Logically Collective
738: Input Parameters:
739: + pc - the preconditioner context
740: - matapplytranspose - the application-provided preconditioning transpose routine
742: Calling sequence of `matapplytranspose`:
743: + pc - the preconditioner
744: . xin - input matrix
745: - xout - output matrix
747: Level: intermediate
749: Note:
750: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `matapplytranspose`.
752: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellSetApplyBA()`, `PCShellGetContext()`
753: @*/
754: PetscErrorCode PCShellSetMatApplyTranspose(PC pc, PetscErrorCode (*matapplytranspose)(PC pc, Mat xin, Mat xout))
755: {
756: PetscFunctionBegin;
758: PetscTryMethod(pc, "PCShellSetMatApplyTranspose_C", (PC, PetscErrorCode (*)(PC, Mat, Mat)), (pc, matapplytranspose));
759: PetscFunctionReturn(PETSC_SUCCESS);
760: }
762: /*@
763: PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a `KSPSolve()` is
764: applied. This usually does something like scale the linear system in some application
765: specific way.
767: Logically Collective
769: Input Parameters:
770: + pc - the preconditioner context
771: - presolve - the application-provided presolve routine, see `PCShellPSolveFn`
773: Level: advanced
775: Note:
776: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `presolve`.
778: .seealso: [](ch_ksp), `PCSHELL`, `PCShellPSolveFn`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetPostSolve()`, `PCShellSetContext()`, `PCShellGetContext()`
779: @*/
780: PetscErrorCode PCShellSetPreSolve(PC pc, PCShellPSolveFn *presolve)
781: {
782: PetscFunctionBegin;
784: PetscTryMethod(pc, "PCShellSetPreSolve_C", (PC, PCShellPSolveFn *), (pc, presolve));
785: PetscFunctionReturn(PETSC_SUCCESS);
786: }
788: /*@
789: PCShellSetPostSolve - Sets routine to apply to the operators/vectors after a `KSPSolve()` is
790: applied. This usually does something like scale the linear system in some application
791: specific way.
793: Logically Collective
795: Input Parameters:
796: + pc - the preconditioner context
797: - postsolve - the application-provided postsolve routine, see `PCShellPSolveFn`
799: Level: advanced
801: Note:
802: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `postsolve`.
804: .seealso: [](ch_ksp), `PCSHELL`, `PCShellPSolveFn`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetPreSolve()`, `PCShellSetContext()`, `PCShellGetContext()`
805: @*/
806: PetscErrorCode PCShellSetPostSolve(PC pc, PCShellPSolveFn *postsolve)
807: {
808: PetscFunctionBegin;
810: PetscTryMethod(pc, "PCShellSetPostSolve_C", (PC, PCShellPSolveFn *), (pc, postsolve));
811: PetscFunctionReturn(PETSC_SUCCESS);
812: }
814: /*@
815: PCShellSetName - Sets an optional name to associate with a `PCSHELL`
816: preconditioner.
818: Not Collective
820: Input Parameters:
821: + pc - the preconditioner context
822: - name - character string describing shell preconditioner
824: Level: intermediate
826: Note:
827: This is separate from the name you can provide with `PetscObjectSetName()`
829: .seealso: [](ch_ksp), `PCSHELL`, `PCShellGetName()`, `PetscObjectSetName()`, `PetscObjectGetName()`
830: @*/
831: PetscErrorCode PCShellSetName(PC pc, const char name[])
832: {
833: PetscFunctionBegin;
835: PetscTryMethod(pc, "PCShellSetName_C", (PC, const char[]), (pc, name));
836: PetscFunctionReturn(PETSC_SUCCESS);
837: }
839: /*@
840: PCShellGetName - Gets an optional name that the user has set for a `PCSHELL` with `PCShellSetName()`
841: preconditioner.
843: Not Collective
845: Input Parameter:
846: . pc - the preconditioner context
848: Output Parameter:
849: . name - character string describing shell preconditioner (you should not free this)
851: Level: intermediate
853: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetName()`, `PetscObjectSetName()`, `PetscObjectGetName()`
854: @*/
855: PetscErrorCode PCShellGetName(PC pc, const char *name[])
856: {
857: PetscFunctionBegin;
859: PetscAssertPointer(name, 2);
860: PetscUseMethod(pc, "PCShellGetName_C", (PC, const char *[]), (pc, name));
861: PetscFunctionReturn(PETSC_SUCCESS);
862: }
864: /*@
865: PCShellSetApplyRichardson - Sets routine to use as preconditioner
866: in Richardson iteration.
868: Logically Collective
870: Input Parameters:
871: + pc - the preconditioner context
872: - apply - the application-provided preconditioning routine
874: Calling sequence of `apply`:
875: + pc - the preconditioner
876: . b - right-hand side
877: . x - current iterate
878: . r - work space
879: . rtol - relative tolerance of residual norm to stop at
880: . abstol - absolute tolerance of residual norm to stop at
881: . dtol - if residual norm increases by this factor than return
882: . maxits - number of iterations to run
883: . zeroinitialguess - `PETSC_TRUE` if `x` is known to be initially zero
884: . its - returns the number of iterations used
885: - reason - returns the reason the iteration has converged
887: Level: advanced
889: Notes:
890: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `apply`.
892: This is used when one can provide code for multiple steps of Richardson's method that is more efficient than computing a single step,
893: recomputing the residual via $ r = b - A x $, and then computing the next step. SOR is an algorithm for which this is true.
895: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetContext()`, `PCRichardsonConvergedReason()`, `PCShellGetContext()`, `PCShellSetMatApplyRichardson()`, `KSPRICHARDSON`
896: @*/
897: PetscErrorCode PCShellSetApplyRichardson(PC pc, PetscErrorCode (*apply)(PC pc, Vec b, Vec x, Vec r, PetscReal rtol, PetscReal abstol, PetscReal dtol, PetscInt maxits, PetscBool zeroinitialguess, PetscInt *its, PCRichardsonConvergedReason *reason))
898: {
899: PetscFunctionBegin;
901: PetscTryMethod(pc, "PCShellSetApplyRichardson_C", (PC, PetscErrorCode (*)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)), (pc, apply));
902: PetscFunctionReturn(PETSC_SUCCESS);
903: }
905: /*@
906: PCShellSetMatApplyRichardson - Sets routine to use as preconditioner
907: in Richardson iteration on a block of vectors stored as a `MATDENSE`.
909: Logically Collective
911: Input Parameters:
912: + pc - the preconditioner context
913: - matapply - the application-provided preconditioning routine
915: Calling sequence of `matapply`:
916: + pc - the preconditioner
917: . B - block of right-hand sides
918: . X - block of current iterates
919: . W - block of work vectors, may be `NULL`
920: . rtol - relative tolerance of residual norm to stop at
921: . abstol - absolute tolerance of residual norm to stop at
922: . dtol - if residual norm increases by this factor then return
923: . maxits - number of iterations to run
924: . zeroinitialguess - `PETSC_TRUE` if `X` is known to be initially zero
925: . its - returns the number of iterations used
926: - reason - returns the reason the iteration has converged
928: Level: advanced
930: Notes:
931: You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `matapply`.
933: This is the block analog of `PCShellSetApplyRichardson()` and is used by `KSPMatSolve()` with `KSPRICHARDSON` to run Richardson's
934: method on the whole block of right-hand sides at once instead of one right-hand side at a time. `KSPRICHARDSON` passes `NULL` for
935: `W`, so `matapply` must allocate any scratch space it needs itself. Setting this callback without also setting
936: `PCShellSetApplyRichardson()` makes `KSPMatSolve()` delegate to `matapply` while `KSPSolve()` runs the generic Richardson
937: iteration with the plain apply callback, so the two can compute different solutions unless the callbacks are consistent.
939: .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetMatApply()`, `PCShellSetContext()`, `PCRichardsonConvergedReason()`, `PCShellGetContext()`, `KSPRICHARDSON`, `KSPMatSolve()`
940: @*/
941: PetscErrorCode PCShellSetMatApplyRichardson(PC pc, PetscErrorCode (*matapply)(PC pc, Mat B, Mat X, Mat W, PetscReal rtol, PetscReal abstol, PetscReal dtol, PetscInt maxits, PetscBool zeroinitialguess, PetscInt *its, PCRichardsonConvergedReason *reason))
942: {
943: PetscFunctionBegin;
945: PetscTryMethod(pc, "PCShellSetMatApplyRichardson_C", (PC, PetscErrorCode (*)(PC, Mat, Mat, Mat, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)), (pc, matapply));
946: PetscFunctionReturn(PETSC_SUCCESS);
947: }
949: /*MC
950: PCSHELL - Creates a new preconditioner class for use with a users
951: own private data storage format and preconditioner application code
953: Level: advanced
955: Usage:
956: .vb
957: extern PetscErrorCode apply(PC,Vec,Vec);
958: extern PetscErrorCode applyba(PC,PCSide,Vec,Vec,Vec);
959: extern PetscErrorCode applytranspose(PC,Vec,Vec);
960: extern PetscErrorCode setup(PC);
961: extern PetscErrorCode destroy(PC);
963: PCCreate(comm,&pc);
964: PCSetType(pc,PCSHELL);
965: PCShellSetContext(pc,ctx)
966: PCShellSetApply(pc,apply);
967: PCShellSetApplyBA(pc,applyba); (optional)
968: PCShellSetApplyTranspose(pc,applytranspose); (optional)
969: PCShellSetSetUp(pc,setup); (optional)
970: PCShellSetDestroy(pc,destroy); (optional)
971: .ve
973: Notes:
974: Information required for the preconditioner and its internal datastructures can be set with `PCShellSetContext()` and then accessed
975: with `PCShellGetContext()` inside the routines provided above.
977: When using `MATSHELL`, where the explicit entries of matrix are not available to build the preconditioner, `PCSHELL` can be used
978: to construct a custom preconditioner for the `MATSHELL`, assuming the user knows enough about their problem to provide a
979: custom preconditioner.
981: .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`,
982: `MATSHELL`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetView()`, `PCShellSetDestroy()`, `PCShellSetPostSolve()`,
983: `PCShellSetApplyTranspose()`, `PCShellSetName()`, `PCShellSetApplyRichardson()`, `PCShellSetPreSolve()`,
984: `PCShellGetName()`, `PCShellSetContext()`, `PCShellGetContext()`, `PCShellSetApplyBA()`, `PCShellSetMatApply()`, `PCShellSetMatApplyRichardson()`
985: M*/
987: PETSC_EXTERN PetscErrorCode PCCreate_Shell(PC pc)
988: {
989: PC_Shell *shell;
991: PetscFunctionBegin;
992: PetscCall(PetscNew(&shell));
993: pc->data = (void *)shell;
995: pc->ops->destroy = PCDestroy_Shell;
996: pc->ops->view = PCView_Shell;
997: pc->ops->apply = PCApply_Shell;
998: pc->ops->applysymmetricleft = PCApplySymmetricLeft_Shell;
999: pc->ops->applysymmetricright = PCApplySymmetricRight_Shell;
1000: pc->ops->matapply = NULL;
1001: pc->ops->applytranspose = NULL;
1002: pc->ops->applyrichardson = NULL;
1003: pc->ops->matapplyrichardson = NULL;
1004: pc->ops->setup = NULL;
1005: pc->ops->presolve = NULL;
1006: pc->ops->postsolve = NULL;
1008: shell->apply = NULL;
1009: shell->applytranspose = NULL;
1010: shell->name = NULL;
1011: shell->applyrich = NULL;
1012: shell->matapplyrich = NULL;
1013: shell->presolve = NULL;
1014: shell->postsolve = NULL;
1015: shell->ctx = NULL;
1016: shell->setup = NULL;
1017: shell->view = NULL;
1018: shell->destroy = NULL;
1019: shell->applysymmetricleft = NULL;
1020: shell->applysymmetricright = NULL;
1022: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetDestroy_C", PCShellSetDestroy_Shell));
1023: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetSetUp_C", PCShellSetSetUp_Shell));
1024: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApply_C", PCShellSetApply_Shell));
1025: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApply_C", PCShellSetMatApply_Shell));
1026: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricLeft_C", PCShellSetApplySymmetricLeft_Shell));
1027: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricRight_C", PCShellSetApplySymmetricRight_Shell));
1028: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyBA_C", PCShellSetApplyBA_Shell));
1029: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPreSolve_C", PCShellSetPreSolve_Shell));
1030: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPostSolve_C", PCShellSetPostSolve_Shell));
1031: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetView_C", PCShellSetView_Shell));
1032: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyTranspose_C", PCShellSetApplyTranspose_Shell));
1033: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApplyTranspose_C", PCShellSetMatApplyTranspose_Shell));
1034: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetName_C", PCShellSetName_Shell));
1035: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellGetName_C", PCShellGetName_Shell));
1036: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyRichardson_C", PCShellSetApplyRichardson_Shell));
1037: PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApplyRichardson_C", PCShellSetMatApplyRichardson_Shell));
1038: PetscFunctionReturn(PETSC_SUCCESS);
1039: }