Actual source code: snesshell.c
1: #include <petsc/private/snesimpl.h>
3: typedef struct {
4: PetscErrorCode (*solve)(SNES, Vec);
5: void *ctx;
6: } SNES_Shell;
8: /*@C
9: SNESShellSetSolve - Sets routine to apply as solver
11: Logically Collective
13: Input Parameters:
14: + snes - the `SNES` nonlinear solver context
15: - apply - the application-provided solver routine
17: Calling sequence of `apply`:
18: .vb
19: PetscErrorCode apply(SNES snes, Vec xout)
20: .ve
21: + snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()`
22: - xout - solution vector
24: Level: advanced
26: .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()`
27: @*/
28: PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
29: {
30: PetscFunctionBegin;
32: PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve));
33: PetscFunctionReturn(PETSC_SUCCESS);
34: }
36: PetscErrorCode SNESReset_Shell(SNES snes)
37: {
38: PetscFunctionBegin;
39: PetscFunctionReturn(PETSC_SUCCESS);
40: }
42: PetscErrorCode SNESDestroy_Shell(SNES snes)
43: {
44: PetscFunctionBegin;
45: PetscCall(SNESReset_Shell(snes));
46: PetscCall(PetscFree(snes->data));
47: PetscFunctionReturn(PETSC_SUCCESS);
48: }
50: PetscErrorCode SNESSetUp_Shell(SNES snes)
51: {
52: PetscFunctionBegin;
53: PetscFunctionReturn(PETSC_SUCCESS);
54: }
56: PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject)
57: {
58: PetscFunctionBegin;
59: PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options");
60: PetscFunctionReturn(PETSC_SUCCESS);
61: }
63: PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer)
64: {
65: PetscFunctionBegin;
66: PetscFunctionReturn(PETSC_SUCCESS);
67: }
69: /*@
70: SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
72: Not Collective
74: Input Parameter:
75: . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
77: Output Parameter:
78: . ctx - the user provided context
80: Level: advanced
82: .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
83: @*/
84: PetscErrorCode SNESShellGetContext(SNES snes, void *ctx)
85: {
86: PetscBool flg;
88: PetscFunctionBegin;
91: PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
92: if (!flg) *(void **)ctx = NULL;
93: else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx;
94: PetscFunctionReturn(PETSC_SUCCESS);
95: }
97: /*@
98: SNESShellSetContext - sets the context for a `SNESSHELL`
100: Logically Collective
102: Input Parameters:
103: + snes - the `SNESSHELL`
104: - ctx - the context
106: Level: advanced
108: Fortran Note:
109: The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type.
111: .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
112: @*/
113: PetscErrorCode SNESShellSetContext(SNES snes, void *ctx)
114: {
115: SNES_Shell *shell = (SNES_Shell *)snes->data;
116: PetscBool flg;
118: PetscFunctionBegin;
120: PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
121: if (flg) shell->ctx = ctx;
122: PetscFunctionReturn(PETSC_SUCCESS);
123: }
125: PetscErrorCode SNESSolve_Shell(SNES snes)
126: {
127: SNES_Shell *shell = (SNES_Shell *)snes->data;
129: PetscFunctionBegin;
130: PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
131: snes->reason = SNES_CONVERGED_ITS;
132: PetscCall((*shell->solve)(snes, snes->vec_sol));
133: PetscFunctionReturn(PETSC_SUCCESS);
134: }
136: PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
137: {
138: SNES_Shell *shell = (SNES_Shell *)snes->data;
140: PetscFunctionBegin;
141: shell->solve = solve;
142: PetscFunctionReturn(PETSC_SUCCESS);
143: }
145: /*MC
146: SNESSHELL - a user provided nonlinear solver
148: Level: advanced
150: .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
151: M*/
153: PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
154: {
155: SNES_Shell *shell;
157: PetscFunctionBegin;
158: snes->ops->destroy = SNESDestroy_Shell;
159: snes->ops->setup = SNESSetUp_Shell;
160: snes->ops->setfromoptions = SNESSetFromOptions_Shell;
161: snes->ops->view = SNESView_Shell;
162: snes->ops->solve = SNESSolve_Shell;
163: snes->ops->reset = SNESReset_Shell;
165: snes->usesksp = PETSC_FALSE;
166: snes->usesnpc = PETSC_FALSE;
168: snes->alwayscomputesfinalresidual = PETSC_FALSE;
170: PetscCall(PetscNew(&shell));
171: snes->data = (void *)shell;
172: PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
173: PetscFunctionReturn(PETSC_SUCCESS);
174: }