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 solve:
18: .vb
19: PetscErrorCode apply (SNES snes,Vec xout)
20: .ve
22: + snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()`
23: - xout - solution vector
25: Level: advanced
27: .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()`
28: @*/
29: PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
30: {
31: PetscFunctionBegin;
33: PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve));
34: PetscFunctionReturn(PETSC_SUCCESS);
35: }
37: PetscErrorCode SNESReset_Shell(SNES snes)
38: {
39: PetscFunctionBegin;
40: PetscFunctionReturn(PETSC_SUCCESS);
41: }
43: PetscErrorCode SNESDestroy_Shell(SNES snes)
44: {
45: PetscFunctionBegin;
46: PetscCall(SNESReset_Shell(snes));
47: PetscCall(PetscFree(snes->data));
48: PetscFunctionReturn(PETSC_SUCCESS);
49: }
51: PetscErrorCode SNESSetUp_Shell(SNES snes)
52: {
53: PetscFunctionBegin;
54: PetscFunctionReturn(PETSC_SUCCESS);
55: }
57: PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject)
58: {
59: PetscFunctionBegin;
60: PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options");
61: PetscFunctionReturn(PETSC_SUCCESS);
62: }
64: PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer)
65: {
66: PetscFunctionBegin;
67: PetscFunctionReturn(PETSC_SUCCESS);
68: }
70: /*@
71: SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
73: Not Collective
75: Input Parameter:
76: . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
78: Output Parameter:
79: . ctx - the user provided context
81: Level: advanced
83: .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
84: @*/
85: PetscErrorCode SNESShellGetContext(SNES snes, void *ctx)
86: {
87: PetscBool flg;
89: PetscFunctionBegin;
92: PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
93: if (!flg) *(void **)ctx = NULL;
94: else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx;
95: PetscFunctionReturn(PETSC_SUCCESS);
96: }
98: /*@
99: SNESShellSetContext - sets the context for a `SNESSHELL`
101: Logically Collective
103: Input Parameters:
104: + snes - the `SNESSHELL`
105: - ctx - the context
107: Level: advanced
109: Fortran Note:
110: The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type.
112: .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
113: @*/
114: PetscErrorCode SNESShellSetContext(SNES snes, void *ctx)
115: {
116: SNES_Shell *shell = (SNES_Shell *)snes->data;
117: PetscBool flg;
119: PetscFunctionBegin;
121: PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
122: if (flg) shell->ctx = ctx;
123: PetscFunctionReturn(PETSC_SUCCESS);
124: }
126: PetscErrorCode SNESSolve_Shell(SNES snes)
127: {
128: SNES_Shell *shell = (SNES_Shell *)snes->data;
130: PetscFunctionBegin;
131: PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
132: snes->reason = SNES_CONVERGED_ITS;
133: PetscCall((*shell->solve)(snes, snes->vec_sol));
134: PetscFunctionReturn(PETSC_SUCCESS);
135: }
137: PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
138: {
139: SNES_Shell *shell = (SNES_Shell *)snes->data;
141: PetscFunctionBegin;
142: shell->solve = solve;
143: PetscFunctionReturn(PETSC_SUCCESS);
144: }
146: /*MC
147: SNESSHELL - a user provided nonlinear solver
149: Level: advanced
151: .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
152: M*/
154: PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
155: {
156: SNES_Shell *shell;
158: PetscFunctionBegin;
159: snes->ops->destroy = SNESDestroy_Shell;
160: snes->ops->setup = SNESSetUp_Shell;
161: snes->ops->setfromoptions = SNESSetFromOptions_Shell;
162: snes->ops->view = SNESView_Shell;
163: snes->ops->solve = SNESSolve_Shell;
164: snes->ops->reset = SNESReset_Shell;
166: snes->usesksp = PETSC_FALSE;
167: snes->usesnpc = PETSC_FALSE;
169: snes->alwayscomputesfinalresidual = PETSC_FALSE;
171: PetscCall(PetscNew(&shell));
172: snes->data = (void *)shell;
173: PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
174: PetscFunctionReturn(PETSC_SUCCESS);
175: }