1 /*
2 This provides a simple shell for Fortran (and C programmers) to
3 create their own preconditioner without writing much interface code.
4 */
5
6 #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
7
8 typedef struct {
9 PetscCtx ctx; /* user provided contexts for preconditioner */
10
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
25 char *name;
26 } PC_Shell;
27
28 /*@C
29 PCShellGetContext - Returns the user-provided context associated with a shell `PC` that was provided with `PCShellSetContext()`
30
31 Not Collective
32
33 Input Parameter:
34 . pc - of type `PCSHELL`
35
36 Output Parameter:
37 . ctx - the user provided context
38
39 Level: advanced
40
41 Note:
42 This routine is intended for use within the various user-provided routines set with, for example, `PCShellSetApply()`
43
44 Fortran Notes:
45 This only works when the context is a Fortran derived type or a `PetscObject`. Define `ctx` with
46 .vb
47 type(tUsertype), pointer :: ctx
48 .ve
49
50 .seealso: [](ch_ksp), `PC`, `PCSHELL`, `PCShellSetContext()`, `PCShellSetApply()`, `PCShellSetDestroy()`
51 @*/
PCShellGetContext(PC pc,PetscCtxRt ctx)52 PetscErrorCode PCShellGetContext(PC pc, PetscCtxRt ctx)
53 {
54 PetscBool flg;
55
56 PetscFunctionBegin;
57 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
58 PetscAssertPointer(ctx, 2);
59 PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCSHELL, &flg));
60 if (!flg) *(void **)ctx = NULL;
61 else *(void **)ctx = ((PC_Shell *)pc->data)->ctx;
62 PetscFunctionReturn(PETSC_SUCCESS);
63 }
64
65 /*@
66 PCShellSetContext - sets the context for a shell `PC` that can be accessed with `PCShellGetContext()`
67
68 Logically Collective
69
70 Input Parameters:
71 + pc - the `PC` of type `PCSHELL`
72 - ctx - the context
73
74 Level: advanced
75
76 Notes:
77 This routine is intended for use within the various user-provided routines set with, for example, `PCShellSetApply()`
78
79 One should also provide a routine to destroy the context when `pc` is destroyed with `PCShellSetDestroy()`
80
81 Fortran Notes:
82 To use this from Fortran you must write a Fortran interface definition for this
83 function that tells Fortran the Fortran derived data type that you are passing in as the `ctx` argument.
84
85 .seealso: [](ch_ksp), `PC`, `PCShellGetContext()`, `PCSHELL`, `PCShellSetApply()`, `PCShellSetDestroy()`
86 @*/
PCShellSetContext(PC pc,PetscCtx ctx)87 PetscErrorCode PCShellSetContext(PC pc, PetscCtx ctx)
88 {
89 PC_Shell *shell = (PC_Shell *)pc->data;
90 PetscBool flg;
91
92 PetscFunctionBegin;
93 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
94 PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCSHELL, &flg));
95 if (flg) shell->ctx = ctx;
96 PetscFunctionReturn(PETSC_SUCCESS);
97 }
98
PCSetUp_Shell(PC pc)99 static PetscErrorCode PCSetUp_Shell(PC pc)
100 {
101 PC_Shell *shell = (PC_Shell *)pc->data;
102
103 PetscFunctionBegin;
104 PetscCheck(shell->setup, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No setup() routine provided to Shell PC");
105 PetscCallBack("PCSHELL callback setup", (*shell->setup)(pc));
106 PetscFunctionReturn(PETSC_SUCCESS);
107 }
108
PCApply_Shell(PC pc,Vec x,Vec y)109 static PetscErrorCode PCApply_Shell(PC pc, Vec x, Vec y)
110 {
111 PC_Shell *shell = (PC_Shell *)pc->data;
112 PetscObjectState instate, outstate;
113
114 PetscFunctionBegin;
115 PetscCheck(shell->apply, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
116 PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
117 PetscCallBack("PCSHELL callback apply", (*shell->apply)(pc, x, y));
118 PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
119 /* increase the state of the output vector if the user did not update its state themself as should have been done */
120 if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
121 PetscFunctionReturn(PETSC_SUCCESS);
122 }
123
PCMatApply_Shell(PC pc,Mat X,Mat Y)124 static PetscErrorCode PCMatApply_Shell(PC pc, Mat X, Mat Y)
125 {
126 PC_Shell *shell = (PC_Shell *)pc->data;
127 PetscObjectState instate, outstate;
128
129 PetscFunctionBegin;
130 PetscCheck(shell->matapply, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
131 PetscCall(PetscObjectStateGet((PetscObject)Y, &instate));
132 PetscCallBack("PCSHELL callback apply", (*shell->matapply)(pc, X, Y));
133 PetscCall(PetscObjectStateGet((PetscObject)Y, &outstate));
134 /* increase the state of the output vector if the user did not update its state themself as should have been done */
135 if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)Y));
136 PetscFunctionReturn(PETSC_SUCCESS);
137 }
138
PCApplySymmetricLeft_Shell(PC pc,Vec x,Vec y)139 static PetscErrorCode PCApplySymmetricLeft_Shell(PC pc, Vec x, Vec y)
140 {
141 PC_Shell *shell = (PC_Shell *)pc->data;
142
143 PetscFunctionBegin;
144 PetscCheck(shell->applysymmetricleft, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
145 PetscCallBack("PCSHELL callback apply symmetric left", (*shell->applysymmetricleft)(pc, x, y));
146 PetscFunctionReturn(PETSC_SUCCESS);
147 }
148
PCApplySymmetricRight_Shell(PC pc,Vec x,Vec y)149 static PetscErrorCode PCApplySymmetricRight_Shell(PC pc, Vec x, Vec y)
150 {
151 PC_Shell *shell = (PC_Shell *)pc->data;
152
153 PetscFunctionBegin;
154 PetscCheck(shell->applysymmetricright, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
155 PetscCallBack("PCSHELL callback apply symmetric right", (*shell->applysymmetricright)(pc, x, y));
156 PetscFunctionReturn(PETSC_SUCCESS);
157 }
158
PCApplyBA_Shell(PC pc,PCSide side,Vec x,Vec y,Vec w)159 static PetscErrorCode PCApplyBA_Shell(PC pc, PCSide side, Vec x, Vec y, Vec w)
160 {
161 PC_Shell *shell = (PC_Shell *)pc->data;
162 PetscObjectState instate, outstate;
163
164 PetscFunctionBegin;
165 PetscCheck(shell->applyBA, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applyBA() routine provided to Shell PC");
166 PetscCall(PetscObjectStateGet((PetscObject)w, &instate));
167 PetscCallBack("PCSHELL callback applyBA", (*shell->applyBA)(pc, side, x, y, w));
168 PetscCall(PetscObjectStateGet((PetscObject)w, &outstate));
169 /* increase the state of the output vector if the user did not update its state themself as should have been done */
170 if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)w));
171 PetscFunctionReturn(PETSC_SUCCESS);
172 }
173
PCPreSolveChangeRHS_Shell(PC pc,PetscBool * change)174 static PetscErrorCode PCPreSolveChangeRHS_Shell(PC pc, PetscBool *change)
175 {
176 PetscFunctionBegin;
177 *change = PETSC_TRUE;
178 PetscFunctionReturn(PETSC_SUCCESS);
179 }
180
PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)181 static PetscErrorCode PCPreSolve_Shell(PC pc, KSP ksp, Vec b, Vec x)
182 {
183 PC_Shell *shell = (PC_Shell *)pc->data;
184
185 PetscFunctionBegin;
186 PetscCheck(shell->presolve, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No presolve() routine provided to Shell PC");
187 PetscCallBack("PCSHELL callback presolve", (*shell->presolve)(pc, ksp, b, x));
188 PetscFunctionReturn(PETSC_SUCCESS);
189 }
190
PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)191 static PetscErrorCode PCPostSolve_Shell(PC pc, KSP ksp, Vec b, Vec x)
192 {
193 PC_Shell *shell = (PC_Shell *)pc->data;
194
195 PetscFunctionBegin;
196 PetscCheck(shell->postsolve, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No postsolve() routine provided to Shell PC");
197 PetscCallBack("PCSHELL callback postsolve()", (*shell->postsolve)(pc, ksp, b, x));
198 PetscFunctionReturn(PETSC_SUCCESS);
199 }
200
PCApplyTranspose_Shell(PC pc,Vec x,Vec y)201 static PetscErrorCode PCApplyTranspose_Shell(PC pc, Vec x, Vec y)
202 {
203 PC_Shell *shell = (PC_Shell *)pc->data;
204 PetscObjectState instate, outstate;
205
206 PetscFunctionBegin;
207 PetscCheck(shell->applytranspose, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applytranspose() routine provided to Shell PC");
208 PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
209 PetscCallBack("PCSHELL callback applytranspose", (*shell->applytranspose)(pc, x, y));
210 PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
211 /* increase the state of the output vector if the user did not update its state themself as should have been done */
212 if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
213 PetscFunctionReturn(PETSC_SUCCESS);
214 }
215
PCMatApplyTranspose_Shell(PC pc,Mat x,Mat y)216 static PetscErrorCode PCMatApplyTranspose_Shell(PC pc, Mat x, Mat y)
217 {
218 PC_Shell *shell = (PC_Shell *)pc->data;
219 PetscObjectState instate, outstate;
220
221 PetscFunctionBegin;
222 PetscCheck(shell->matapplytranspose, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No matapplytranspose() routine provided to Shell PC");
223 PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
224 PetscCallBack("PCSHELL callback matapplytranspose", (*shell->matapplytranspose)(pc, x, y));
225 PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
226 /* increase the state of the output matrix if the user did not update its state themself as should have been done */
227 if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
228 PetscFunctionReturn(PETSC_SUCCESS);
229 }
230
PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt it,PetscBool guesszero,PetscInt * outits,PCRichardsonConvergedReason * reason)231 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)
232 {
233 PC_Shell *shell = (PC_Shell *)pc->data;
234 PetscObjectState instate, outstate;
235
236 PetscFunctionBegin;
237 PetscCheck(shell->applyrich, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applyrichardson() routine provided to Shell PC");
238 PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
239 PetscCallBack("PCSHELL callback applyrichardson", (*shell->applyrich)(pc, x, y, w, rtol, abstol, dtol, it, guesszero, outits, reason));
240 PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
241 /* increase the state of the output vector since the user did not update its state themself as should have been done */
242 if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
243 PetscFunctionReturn(PETSC_SUCCESS);
244 }
245
PCDestroy_Shell(PC pc)246 static PetscErrorCode PCDestroy_Shell(PC pc)
247 {
248 PC_Shell *shell = (PC_Shell *)pc->data;
249
250 PetscFunctionBegin;
251 PetscCall(PetscFree(shell->name));
252 if (shell->destroy) PetscCallBack("PCSHELL callback destroy", (*shell->destroy)(pc));
253 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetDestroy_C", NULL));
254 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetSetUp_C", NULL));
255 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApply_C", NULL));
256 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApply_C", NULL));
257 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricLeft_C", NULL));
258 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricRight_C", NULL));
259 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyBA_C", NULL));
260 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPreSolve_C", NULL));
261 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPostSolve_C", NULL));
262 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetView_C", NULL));
263 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyTranspose_C", NULL));
264 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApplyTranspose_C", NULL));
265 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetName_C", NULL));
266 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellGetName_C", NULL));
267 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyRichardson_C", NULL));
268 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", NULL));
269 PetscCall(PetscFree(pc->data));
270 PetscFunctionReturn(PETSC_SUCCESS);
271 }
272
PCView_Shell(PC pc,PetscViewer viewer)273 static PetscErrorCode PCView_Shell(PC pc, PetscViewer viewer)
274 {
275 PC_Shell *shell = (PC_Shell *)pc->data;
276 PetscBool isascii;
277
278 PetscFunctionBegin;
279 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
280 if (isascii) {
281 if (shell->name) PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", shell->name));
282 else PetscCall(PetscViewerASCIIPrintf(viewer, " no name\n"));
283 }
284 if (shell->view) {
285 PetscCall(PetscViewerASCIIPushTab(viewer));
286 PetscCall((*shell->view)(pc, viewer));
287 PetscCall(PetscViewerASCIIPopTab(viewer));
288 }
289 PetscFunctionReturn(PETSC_SUCCESS);
290 }
291
PCShellSetDestroy_Shell(PC pc,PetscErrorCode (* destroy)(PC))292 static PetscErrorCode PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(PC))
293 {
294 PC_Shell *shell = (PC_Shell *)pc->data;
295
296 PetscFunctionBegin;
297 shell->destroy = destroy;
298 PetscFunctionReturn(PETSC_SUCCESS);
299 }
300
PCShellSetSetUp_Shell(PC pc,PetscErrorCode (* setup)(PC))301 static PetscErrorCode PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(PC))
302 {
303 PC_Shell *shell = (PC_Shell *)pc->data;
304
305 PetscFunctionBegin;
306 shell->setup = setup;
307 if (setup) pc->ops->setup = PCSetUp_Shell;
308 else pc->ops->setup = NULL;
309 PetscFunctionReturn(PETSC_SUCCESS);
310 }
311
PCShellSetApply_Shell(PC pc,PetscErrorCode (* apply)(PC,Vec,Vec))312 static PetscErrorCode PCShellSetApply_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec))
313 {
314 PC_Shell *shell = (PC_Shell *)pc->data;
315
316 PetscFunctionBegin;
317 shell->apply = apply;
318 PetscFunctionReturn(PETSC_SUCCESS);
319 }
320
PCShellSetMatApply_Shell(PC pc,PetscErrorCode (* matapply)(PC,Mat,Mat))321 static PetscErrorCode PCShellSetMatApply_Shell(PC pc, PetscErrorCode (*matapply)(PC, Mat, Mat))
322 {
323 PC_Shell *shell = (PC_Shell *)pc->data;
324
325 PetscFunctionBegin;
326 shell->matapply = matapply;
327 if (matapply) pc->ops->matapply = PCMatApply_Shell;
328 else pc->ops->matapply = NULL;
329 PetscFunctionReturn(PETSC_SUCCESS);
330 }
331
PCShellSetApplySymmetricLeft_Shell(PC pc,PetscErrorCode (* apply)(PC,Vec,Vec))332 static PetscErrorCode PCShellSetApplySymmetricLeft_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec))
333 {
334 PC_Shell *shell = (PC_Shell *)pc->data;
335
336 PetscFunctionBegin;
337 shell->applysymmetricleft = apply;
338 PetscFunctionReturn(PETSC_SUCCESS);
339 }
340
PCShellSetApplySymmetricRight_Shell(PC pc,PetscErrorCode (* apply)(PC,Vec,Vec))341 static PetscErrorCode PCShellSetApplySymmetricRight_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec))
342 {
343 PC_Shell *shell = (PC_Shell *)pc->data;
344
345 PetscFunctionBegin;
346 shell->applysymmetricright = apply;
347 PetscFunctionReturn(PETSC_SUCCESS);
348 }
349
PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (* applyBA)(PC,PCSide,Vec,Vec,Vec))350 static PetscErrorCode PCShellSetApplyBA_Shell(PC pc, PetscErrorCode (*applyBA)(PC, PCSide, Vec, Vec, Vec))
351 {
352 PC_Shell *shell = (PC_Shell *)pc->data;
353
354 PetscFunctionBegin;
355 shell->applyBA = applyBA;
356 if (applyBA) pc->ops->applyBA = PCApplyBA_Shell;
357 else pc->ops->applyBA = NULL;
358 PetscFunctionReturn(PETSC_SUCCESS);
359 }
360
PCShellSetPreSolve_Shell(PC pc,PCShellPSolveFn * presolve)361 static PetscErrorCode PCShellSetPreSolve_Shell(PC pc, PCShellPSolveFn *presolve)
362 {
363 PC_Shell *shell = (PC_Shell *)pc->data;
364
365 PetscFunctionBegin;
366 shell->presolve = presolve;
367 if (presolve) {
368 pc->ops->presolve = PCPreSolve_Shell;
369 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", PCPreSolveChangeRHS_Shell));
370 } else {
371 pc->ops->presolve = NULL;
372 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", NULL));
373 }
374 PetscFunctionReturn(PETSC_SUCCESS);
375 }
376
PCShellSetPostSolve_Shell(PC pc,PCShellPSolveFn * postsolve)377 static PetscErrorCode PCShellSetPostSolve_Shell(PC pc, PCShellPSolveFn *postsolve)
378 {
379 PC_Shell *shell = (PC_Shell *)pc->data;
380
381 PetscFunctionBegin;
382 shell->postsolve = postsolve;
383 if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
384 else pc->ops->postsolve = NULL;
385 PetscFunctionReturn(PETSC_SUCCESS);
386 }
387
PCShellSetView_Shell(PC pc,PetscErrorCode (* view)(PC,PetscViewer))388 static PetscErrorCode PCShellSetView_Shell(PC pc, PetscErrorCode (*view)(PC, PetscViewer))
389 {
390 PC_Shell *shell = (PC_Shell *)pc->data;
391
392 PetscFunctionBegin;
393 shell->view = view;
394 PetscFunctionReturn(PETSC_SUCCESS);
395 }
396
PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (* applytranspose)(PC,Vec,Vec))397 static PetscErrorCode PCShellSetApplyTranspose_Shell(PC pc, PetscErrorCode (*applytranspose)(PC, Vec, Vec))
398 {
399 PC_Shell *shell = (PC_Shell *)pc->data;
400
401 PetscFunctionBegin;
402 shell->applytranspose = applytranspose;
403 if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
404 else pc->ops->applytranspose = NULL;
405 PetscFunctionReturn(PETSC_SUCCESS);
406 }
407
PCShellSetMatApplyTranspose_Shell(PC pc,PetscErrorCode (* matapplytranspose)(PC,Mat,Mat))408 static PetscErrorCode PCShellSetMatApplyTranspose_Shell(PC pc, PetscErrorCode (*matapplytranspose)(PC, Mat, Mat))
409 {
410 PC_Shell *shell = (PC_Shell *)pc->data;
411
412 PetscFunctionBegin;
413 shell->matapplytranspose = matapplytranspose;
414 if (matapplytranspose) pc->ops->matapplytranspose = PCMatApplyTranspose_Shell;
415 else pc->ops->matapplytranspose = NULL;
416 PetscFunctionReturn(PETSC_SUCCESS);
417 }
418
PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (* applyrich)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool,PetscInt *,PCRichardsonConvergedReason *))419 static PetscErrorCode PCShellSetApplyRichardson_Shell(PC pc, PetscErrorCode (*applyrich)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *))
420 {
421 PC_Shell *shell = (PC_Shell *)pc->data;
422
423 PetscFunctionBegin;
424 shell->applyrich = applyrich;
425 if (applyrich) pc->ops->applyrichardson = PCApplyRichardson_Shell;
426 else pc->ops->applyrichardson = NULL;
427 PetscFunctionReturn(PETSC_SUCCESS);
428 }
429
PCShellSetName_Shell(PC pc,const char name[])430 static PetscErrorCode PCShellSetName_Shell(PC pc, const char name[])
431 {
432 PC_Shell *shell = (PC_Shell *)pc->data;
433
434 PetscFunctionBegin;
435 PetscCall(PetscFree(shell->name));
436 PetscCall(PetscStrallocpy(name, &shell->name));
437 PetscFunctionReturn(PETSC_SUCCESS);
438 }
439
PCShellGetName_Shell(PC pc,const char * name[])440 static PetscErrorCode PCShellGetName_Shell(PC pc, const char *name[])
441 {
442 PC_Shell *shell = (PC_Shell *)pc->data;
443
444 PetscFunctionBegin;
445 *name = shell->name;
446 PetscFunctionReturn(PETSC_SUCCESS);
447 }
448
449 /*@C
450 PCShellSetDestroy - Sets routine to use to destroy the user-provided application context that was provided with `PCShellSetContext()`
451
452 Logically Collective
453
454 Input Parameters:
455 + pc - the preconditioner context
456 - destroy - the application-provided destroy routine
457
458 Calling sequence of `destroy`:
459 . pc - the preconditioner
460
461 Level: intermediate
462
463 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellGetContext()`
464 @*/
PCShellSetDestroy(PC pc,PetscErrorCode (* destroy)(PC pc))465 PetscErrorCode PCShellSetDestroy(PC pc, PetscErrorCode (*destroy)(PC pc))
466 {
467 PetscFunctionBegin;
468 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
469 PetscTryMethod(pc, "PCShellSetDestroy_C", (PC, PetscErrorCode (*)(PC)), (pc, destroy));
470 PetscFunctionReturn(PETSC_SUCCESS);
471 }
472
473 /*@C
474 PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
475 matrix operator is changed.
476
477 Logically Collective
478
479 Input Parameters:
480 + pc - the preconditioner context
481 - setup - the application-provided setup routine
482
483 Calling sequence of `setup`:
484 . pc - the preconditioner
485
486 Level: intermediate
487
488 Note:
489 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `setup`.
490
491 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetApply()`, `PCShellSetContext()`, , `PCShellGetContext()`
492 @*/
PCShellSetSetUp(PC pc,PetscErrorCode (* setup)(PC pc))493 PetscErrorCode PCShellSetSetUp(PC pc, PetscErrorCode (*setup)(PC pc))
494 {
495 PetscFunctionBegin;
496 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
497 PetscTryMethod(pc, "PCShellSetSetUp_C", (PC, PetscErrorCode (*)(PC)), (pc, setup));
498 PetscFunctionReturn(PETSC_SUCCESS);
499 }
500
501 /*@C
502 PCShellSetView - Sets routine to use as viewer of a `PCSHELL` shell preconditioner
503
504 Logically Collective
505
506 Input Parameters:
507 + pc - the preconditioner context
508 - view - the application-provided view routine
509
510 Calling sequence of `view`:
511 + pc - the preconditioner
512 - v - viewer
513
514 Level: advanced
515
516 Note:
517 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `view`.
518
519 .seealso: [](ch_ksp), `PC`, `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellGetContext()`
520 @*/
PCShellSetView(PC pc,PetscErrorCode (* view)(PC pc,PetscViewer v))521 PetscErrorCode PCShellSetView(PC pc, PetscErrorCode (*view)(PC pc, PetscViewer v))
522 {
523 PetscFunctionBegin;
524 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
525 PetscTryMethod(pc, "PCShellSetView_C", (PC, PetscErrorCode (*)(PC, PetscViewer)), (pc, view));
526 PetscFunctionReturn(PETSC_SUCCESS);
527 }
528
529 /*@C
530 PCShellSetApply - Sets routine to use as preconditioner.
531
532 Logically Collective
533
534 Input Parameters:
535 + pc - the preconditioner context
536 - apply - the application-provided preconditioning routine
537
538 Calling sequence of `apply`:
539 + pc - the preconditioner, get the application context with `PCShellGetContext()`
540 . xin - input vector
541 - xout - output vector
542
543 Level: intermediate
544
545 Note:
546 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `apply`.
547
548 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellSetApplyBA()`, `PCShellSetApplySymmetricRight()`, `PCShellSetApplySymmetricLeft()`, `PCShellGetContext()`
549 @*/
PCShellSetApply(PC pc,PetscErrorCode (* apply)(PC pc,Vec xin,Vec xout))550 PetscErrorCode PCShellSetApply(PC pc, PetscErrorCode (*apply)(PC pc, Vec xin, Vec xout))
551 {
552 PetscFunctionBegin;
553 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
554 PetscTryMethod(pc, "PCShellSetApply_C", (PC, PetscErrorCode (*)(PC, Vec, Vec)), (pc, apply));
555 PetscFunctionReturn(PETSC_SUCCESS);
556 }
557
558 /*@C
559 PCShellSetMatApply - Sets routine to use as preconditioner on a block of vectors.
560
561 Logically Collective
562
563 Input Parameters:
564 + pc - the preconditioner context
565 - matapply - the application-provided preconditioning routine
566
567 Calling sequence of `matapply`:
568 + pc - the preconditioner
569 . Xin - input block of vectors represented as a dense `Mat`
570 - Xout - output block of vectors represented as a dense `Mat`
571
572 Level: advanced
573
574 Note:
575 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `matapply`.
576
577 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellGetContext()`
578 @*/
PCShellSetMatApply(PC pc,PetscErrorCode (* matapply)(PC pc,Mat Xin,Mat Xout))579 PetscErrorCode PCShellSetMatApply(PC pc, PetscErrorCode (*matapply)(PC pc, Mat Xin, Mat Xout))
580 {
581 PetscFunctionBegin;
582 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
583 PetscTryMethod(pc, "PCShellSetMatApply_C", (PC, PetscErrorCode (*)(PC, Mat, Mat)), (pc, matapply));
584 PetscFunctionReturn(PETSC_SUCCESS);
585 }
586
587 /*@C
588 PCShellSetApplySymmetricLeft - Sets routine to use as left preconditioner (when the `PC_SYMMETRIC` is used).
589
590 Logically Collective
591
592 Input Parameters:
593 + pc - the preconditioner context
594 - apply - the application-provided left preconditioning routine
595
596 Calling sequence of `apply`:
597 + pc - the preconditioner
598 . xin - input vector
599 - xout - output vector
600
601 Level: advanced
602
603 Note:
604 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `apply`.
605
606 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`
607 @*/
PCShellSetApplySymmetricLeft(PC pc,PetscErrorCode (* apply)(PC pc,Vec xin,Vec xout))608 PetscErrorCode PCShellSetApplySymmetricLeft(PC pc, PetscErrorCode (*apply)(PC pc, Vec xin, Vec xout))
609 {
610 PetscFunctionBegin;
611 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
612 PetscTryMethod(pc, "PCShellSetApplySymmetricLeft_C", (PC, PetscErrorCode (*)(PC, Vec, Vec)), (pc, apply));
613 PetscFunctionReturn(PETSC_SUCCESS);
614 }
615
616 /*@C
617 PCShellSetApplySymmetricRight - Sets routine to use as right preconditioner (when the `PC_SYMMETRIC` is used).
618
619 Logically Collective
620
621 Input Parameters:
622 + pc - the preconditioner context
623 - apply - the application-provided right preconditioning routine
624
625 Calling sequence of `apply`:
626 + pc - the preconditioner
627 . xin - input vector
628 - xout - output vector
629
630 Level: advanced
631
632 Note:
633 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `apply`.
634
635 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetApplySymmetricLeft()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellGetContext()`
636 @*/
PCShellSetApplySymmetricRight(PC pc,PetscErrorCode (* apply)(PC pc,Vec xin,Vec xout))637 PetscErrorCode PCShellSetApplySymmetricRight(PC pc, PetscErrorCode (*apply)(PC pc, Vec xin, Vec xout))
638 {
639 PetscFunctionBegin;
640 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
641 PetscTryMethod(pc, "PCShellSetApplySymmetricRight_C", (PC, PetscErrorCode (*)(PC, Vec, Vec)), (pc, apply));
642 PetscFunctionReturn(PETSC_SUCCESS);
643 }
644
645 /*@C
646 PCShellSetApplyBA - Sets routine to use as the preconditioner times the operator.
647
648 Logically Collective
649
650 Input Parameters:
651 + pc - the preconditioner context
652 - applyBA - the application-provided BA routine
653
654 Calling sequence of `applyBA`:
655 + pc - the preconditioner
656 . side - `PC_LEFT`, `PC_RIGHT`, or `PC_SYMMETRIC`
657 . xin - input vector
658 . xout - output vector
659 - w - work vector
660
661 Level: intermediate
662
663 Note:
664 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `applyBA`.
665
666 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellSetApply()`, `PCShellGetContext()`, `PCSide`
667 @*/
PCShellSetApplyBA(PC pc,PetscErrorCode (* applyBA)(PC pc,PCSide side,Vec xin,Vec xout,Vec w))668 PetscErrorCode PCShellSetApplyBA(PC pc, PetscErrorCode (*applyBA)(PC pc, PCSide side, Vec xin, Vec xout, Vec w))
669 {
670 PetscFunctionBegin;
671 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
672 PetscTryMethod(pc, "PCShellSetApplyBA_C", (PC, PetscErrorCode (*)(PC, PCSide, Vec, Vec, Vec)), (pc, applyBA));
673 PetscFunctionReturn(PETSC_SUCCESS);
674 }
675
676 /*@C
677 PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
678
679 Logically Collective
680
681 Input Parameters:
682 + pc - the preconditioner context
683 - applytranspose - the application-provided preconditioning transpose routine
684
685 Calling sequence of `applytranspose`:
686 + pc - the preconditioner
687 . xin - input vector
688 - xout - output vector
689
690 Level: intermediate
691
692 Note:
693 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `applytranspose`.
694
695 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellSetApplyBA()`, `PCShellGetContext()`
696 @*/
PCShellSetApplyTranspose(PC pc,PetscErrorCode (* applytranspose)(PC pc,Vec xin,Vec xout))697 PetscErrorCode PCShellSetApplyTranspose(PC pc, PetscErrorCode (*applytranspose)(PC pc, Vec xin, Vec xout))
698 {
699 PetscFunctionBegin;
700 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
701 PetscTryMethod(pc, "PCShellSetApplyTranspose_C", (PC, PetscErrorCode (*)(PC, Vec, Vec)), (pc, applytranspose));
702 PetscFunctionReturn(PETSC_SUCCESS);
703 }
704
705 /*@C
706 PCShellSetMatApplyTranspose - Sets routine to use as preconditioner transpose.
707
708 Logically Collective
709
710 Input Parameters:
711 + pc - the preconditioner context
712 - matapplytranspose - the application-provided preconditioning transpose routine
713
714 Calling sequence of `matapplytranspose`:
715 + pc - the preconditioner
716 . xin - input matrix
717 - xout - output matrix
718
719 Level: intermediate
720
721 Note:
722 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `matapplytranspose`.
723
724 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetContext()`, `PCShellSetApplyBA()`, `PCShellGetContext()`
725 @*/
PCShellSetMatApplyTranspose(PC pc,PetscErrorCode (* matapplytranspose)(PC pc,Mat xin,Mat xout))726 PetscErrorCode PCShellSetMatApplyTranspose(PC pc, PetscErrorCode (*matapplytranspose)(PC pc, Mat xin, Mat xout))
727 {
728 PetscFunctionBegin;
729 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
730 PetscTryMethod(pc, "PCShellSetMatApplyTranspose_C", (PC, PetscErrorCode (*)(PC, Mat, Mat)), (pc, matapplytranspose));
731 PetscFunctionReturn(PETSC_SUCCESS);
732 }
733
734 /*@C
735 PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a `KSPSolve()` is
736 applied. This usually does something like scale the linear system in some application
737 specific way.
738
739 Logically Collective
740
741 Input Parameters:
742 + pc - the preconditioner context
743 - presolve - the application-provided presolve routine, see `PCShellPSolveFn`
744
745 Level: advanced
746
747 Note:
748 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `presolve`.
749
750 .seealso: [](ch_ksp), `PCSHELL`, `PCShellPSolveFn`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetPostSolve()`, `PCShellSetContext()`, `PCShellGetContext()`
751 @*/
PCShellSetPreSolve(PC pc,PCShellPSolveFn * presolve)752 PetscErrorCode PCShellSetPreSolve(PC pc, PCShellPSolveFn *presolve)
753 {
754 PetscFunctionBegin;
755 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
756 PetscTryMethod(pc, "PCShellSetPreSolve_C", (PC, PCShellPSolveFn *), (pc, presolve));
757 PetscFunctionReturn(PETSC_SUCCESS);
758 }
759
760 /*@C
761 PCShellSetPostSolve - Sets routine to apply to the operators/vectors after a `KSPSolve()` is
762 applied. This usually does something like scale the linear system in some application
763 specific way.
764
765 Logically Collective
766
767 Input Parameters:
768 + pc - the preconditioner context
769 - postsolve - the application-provided postsolve routine, see `PCShellPSolveFn`
770
771 Level: advanced
772
773 Note:
774 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `postsolve`.
775
776 .seealso: [](ch_ksp), `PCSHELL`, `PCShellPSolveFn`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetPreSolve()`, `PCShellSetContext()`, `PCShellGetContext()`
777 @*/
PCShellSetPostSolve(PC pc,PCShellPSolveFn * postsolve)778 PetscErrorCode PCShellSetPostSolve(PC pc, PCShellPSolveFn *postsolve)
779 {
780 PetscFunctionBegin;
781 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
782 PetscTryMethod(pc, "PCShellSetPostSolve_C", (PC, PCShellPSolveFn *), (pc, postsolve));
783 PetscFunctionReturn(PETSC_SUCCESS);
784 }
785
786 /*@
787 PCShellSetName - Sets an optional name to associate with a `PCSHELL`
788 preconditioner.
789
790 Not Collective
791
792 Input Parameters:
793 + pc - the preconditioner context
794 - name - character string describing shell preconditioner
795
796 Level: intermediate
797
798 Note:
799 This is separate from the name you can provide with `PetscObjectSetName()`
800
801 .seealso: [](ch_ksp), `PCSHELL`, `PCShellGetName()`, `PetscObjectSetName()`, `PetscObjectGetName()`
802 @*/
PCShellSetName(PC pc,const char name[])803 PetscErrorCode PCShellSetName(PC pc, const char name[])
804 {
805 PetscFunctionBegin;
806 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
807 PetscTryMethod(pc, "PCShellSetName_C", (PC, const char[]), (pc, name));
808 PetscFunctionReturn(PETSC_SUCCESS);
809 }
810
811 /*@
812 PCShellGetName - Gets an optional name that the user has set for a `PCSHELL` with `PCShellSetName()`
813 preconditioner.
814
815 Not Collective
816
817 Input Parameter:
818 . pc - the preconditioner context
819
820 Output Parameter:
821 . name - character string describing shell preconditioner (you should not free this)
822
823 Level: intermediate
824
825 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetName()`, `PetscObjectSetName()`, `PetscObjectGetName()`
826 @*/
PCShellGetName(PC pc,const char * name[])827 PetscErrorCode PCShellGetName(PC pc, const char *name[])
828 {
829 PetscFunctionBegin;
830 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
831 PetscAssertPointer(name, 2);
832 PetscUseMethod(pc, "PCShellGetName_C", (PC, const char *[]), (pc, name));
833 PetscFunctionReturn(PETSC_SUCCESS);
834 }
835
836 /*@C
837 PCShellSetApplyRichardson - Sets routine to use as preconditioner
838 in Richardson iteration.
839
840 Logically Collective
841
842 Input Parameters:
843 + pc - the preconditioner context
844 - apply - the application-provided preconditioning routine
845
846 Calling sequence of `apply`:
847 + pc - the preconditioner
848 . b - right-hand side
849 . x - current iterate
850 . r - work space
851 . rtol - relative tolerance of residual norm to stop at
852 . abstol - absolute tolerance of residual norm to stop at
853 . dtol - if residual norm increases by this factor than return
854 . maxits - number of iterations to run
855 . zeroinitialguess - `PETSC_TRUE` if `x` is known to be initially zero
856 . its - returns the number of iterations used
857 - reason - returns the reason the iteration has converged
858
859 Level: advanced
860
861 Notes:
862 You can get the `PCSHELL` context set with `PCShellSetContext()` using `PCShellGetContext()` if needed by `apply`.
863
864 This is used when one can provide code for multiple steps of Richardson's method that is more efficient than computing a single step,
865 recomputing the residual via $ r = b - A x $, and then computing the next step. SOR is an algorithm for which this is true.
866
867 .seealso: [](ch_ksp), `PCSHELL`, `PCShellSetApply()`, `PCShellSetContext()`, `PCRichardsonConvergedReason()`, `PCShellGetContext()`, `KSPRICHARDSON`
868 @*/
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))869 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))
870 {
871 PetscFunctionBegin;
872 PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
873 PetscTryMethod(pc, "PCShellSetApplyRichardson_C", (PC, PetscErrorCode (*)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)), (pc, apply));
874 PetscFunctionReturn(PETSC_SUCCESS);
875 }
876
877 /*MC
878 PCSHELL - Creates a new preconditioner class for use with a users
879 own private data storage format and preconditioner application code
880
881 Level: advanced
882
883 Usage:
884 .vb
885 extern PetscErrorCode apply(PC,Vec,Vec);
886 extern PetscErrorCode applyba(PC,PCSide,Vec,Vec,Vec);
887 extern PetscErrorCode applytranspose(PC,Vec,Vec);
888 extern PetscErrorCode setup(PC);
889 extern PetscErrorCode destroy(PC);
890
891 PCCreate(comm,&pc);
892 PCSetType(pc,PCSHELL);
893 PCShellSetContext(pc,ctx)
894 PCShellSetApply(pc,apply);
895 PCShellSetApplyBA(pc,applyba); (optional)
896 PCShellSetApplyTranspose(pc,applytranspose); (optional)
897 PCShellSetSetUp(pc,setup); (optional)
898 PCShellSetDestroy(pc,destroy); (optional)
899 .ve
900
901 Notes:
902 Information required for the preconditioner and its internal datastructures can be set with `PCShellSetContext()` and then accessed
903 with `PCShellGetContext()` inside the routines provided above.
904
905 When using `MATSHELL`, where the explicit entries of matrix are not available to build the preconditioner, `PCSHELL` can be used
906 to construct a custom preconditioner for the `MATSHELL`, assuming the user knows enough about their problem to provide a
907 custom preconditioner.
908
909 .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`,
910 `MATSHELL`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetView()`, `PCShellSetDestroy()`, `PCShellSetPostSolve()`,
911 `PCShellSetApplyTranspose()`, `PCShellSetName()`, `PCShellSetApplyRichardson()`, `PCShellSetPreSolve()`, `PCShellSetView()`,
912 `PCShellGetName()`, `PCShellSetContext()`, `PCShellGetContext()`, `PCShellSetApplyBA()`, `MATSHELL`, `PCShellSetMatApply()`,
913 M*/
914
PCCreate_Shell(PC pc)915 PETSC_EXTERN PetscErrorCode PCCreate_Shell(PC pc)
916 {
917 PC_Shell *shell;
918
919 PetscFunctionBegin;
920 PetscCall(PetscNew(&shell));
921 pc->data = (void *)shell;
922
923 pc->ops->destroy = PCDestroy_Shell;
924 pc->ops->view = PCView_Shell;
925 pc->ops->apply = PCApply_Shell;
926 pc->ops->applysymmetricleft = PCApplySymmetricLeft_Shell;
927 pc->ops->applysymmetricright = PCApplySymmetricRight_Shell;
928 pc->ops->matapply = NULL;
929 pc->ops->applytranspose = NULL;
930 pc->ops->applyrichardson = NULL;
931 pc->ops->setup = NULL;
932 pc->ops->presolve = NULL;
933 pc->ops->postsolve = NULL;
934
935 shell->apply = NULL;
936 shell->applytranspose = NULL;
937 shell->name = NULL;
938 shell->applyrich = NULL;
939 shell->presolve = NULL;
940 shell->postsolve = NULL;
941 shell->ctx = NULL;
942 shell->setup = NULL;
943 shell->view = NULL;
944 shell->destroy = NULL;
945 shell->applysymmetricleft = NULL;
946 shell->applysymmetricright = NULL;
947
948 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetDestroy_C", PCShellSetDestroy_Shell));
949 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetSetUp_C", PCShellSetSetUp_Shell));
950 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApply_C", PCShellSetApply_Shell));
951 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApply_C", PCShellSetMatApply_Shell));
952 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricLeft_C", PCShellSetApplySymmetricLeft_Shell));
953 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricRight_C", PCShellSetApplySymmetricRight_Shell));
954 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyBA_C", PCShellSetApplyBA_Shell));
955 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPreSolve_C", PCShellSetPreSolve_Shell));
956 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPostSolve_C", PCShellSetPostSolve_Shell));
957 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetView_C", PCShellSetView_Shell));
958 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyTranspose_C", PCShellSetApplyTranspose_Shell));
959 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApplyTranspose_C", PCShellSetMatApplyTranspose_Shell));
960 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetName_C", PCShellSetName_Shell));
961 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellGetName_C", PCShellGetName_Shell));
962 PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyRichardson_C", PCShellSetApplyRichardson_Shell));
963 PetscFunctionReturn(PETSC_SUCCESS);
964 }
965