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 to a `SNESSHELL` `SNES` object
11: Logically Collective
13: Input Parameters:
14: + snes - the `SNES` nonlinear solver context
15: - solve - the application-provided solver routine
17: Calling sequence of `apply`:
18: + snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()`
19: - xout - solution vector
21: Level: advanced
23: .seealso: [](ch_snes), `SNES`, `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()`
24: @*/
25: PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES snes, Vec xout))
26: {
27: PetscFunctionBegin;
29: PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve));
30: PetscFunctionReturn(PETSC_SUCCESS);
31: }
33: static PetscErrorCode SNESReset_Shell(SNES snes)
34: {
35: PetscFunctionBegin;
36: PetscFunctionReturn(PETSC_SUCCESS);
37: }
39: static PetscErrorCode SNESDestroy_Shell(SNES snes)
40: {
41: PetscFunctionBegin;
42: PetscCall(SNESReset_Shell(snes));
43: PetscCall(PetscFree(snes->data));
44: PetscFunctionReturn(PETSC_SUCCESS);
45: }
47: static PetscErrorCode SNESSetUp_Shell(SNES snes)
48: {
49: PetscFunctionBegin;
50: PetscFunctionReturn(PETSC_SUCCESS);
51: }
53: static PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject)
54: {
55: PetscFunctionBegin;
56: PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options");
57: PetscFunctionReturn(PETSC_SUCCESS);
58: }
60: static PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer)
61: {
62: PetscFunctionBegin;
63: PetscFunctionReturn(PETSC_SUCCESS);
64: }
66: /*@
67: SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
69: Not Collective
71: Input Parameter:
72: . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
74: Output Parameter:
75: . ctx - the user provided context
77: Level: advanced
79: .seealso: [](ch_snes), `SNES`, `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
80: @*/
81: PetscErrorCode SNESShellGetContext(SNES snes, void *ctx)
82: {
83: PetscBool flg;
85: PetscFunctionBegin;
87: PetscAssertPointer(ctx, 2);
88: PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
89: if (!flg) *(void **)ctx = NULL;
90: else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx;
91: PetscFunctionReturn(PETSC_SUCCESS);
92: }
94: /*@
95: SNESShellSetContext - sets the context for a `SNESSHELL`
97: Logically Collective
99: Input Parameters:
100: + snes - the `SNESSHELL`
101: - ctx - the context
103: Level: advanced
105: Fortran Note:
106: The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type.
108: .seealso: [](ch_snes), `SNES`, `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
109: @*/
110: PetscErrorCode SNESShellSetContext(SNES snes, void *ctx)
111: {
112: SNES_Shell *shell = (SNES_Shell *)snes->data;
113: PetscBool flg;
115: PetscFunctionBegin;
117: PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
118: if (flg) shell->ctx = ctx;
119: PetscFunctionReturn(PETSC_SUCCESS);
120: }
122: static PetscErrorCode SNESSolve_Shell(SNES snes)
123: {
124: SNES_Shell *shell = (SNES_Shell *)snes->data;
126: PetscFunctionBegin;
127: PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
128: snes->reason = SNES_CONVERGED_ITS;
129: PetscCall((*shell->solve)(snes, snes->vec_sol));
130: PetscFunctionReturn(PETSC_SUCCESS);
131: }
133: static PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
134: {
135: SNES_Shell *shell = (SNES_Shell *)snes->data;
137: PetscFunctionBegin;
138: shell->solve = solve;
139: PetscFunctionReturn(PETSC_SUCCESS);
140: }
142: /*MC
143: SNESSHELL - a user provided nonlinear solver
145: Level: advanced
147: .seealso: [](ch_snes), `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
148: M*/
150: PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
151: {
152: SNES_Shell *shell;
154: PetscFunctionBegin;
155: snes->ops->destroy = SNESDestroy_Shell;
156: snes->ops->setup = SNESSetUp_Shell;
157: snes->ops->setfromoptions = SNESSetFromOptions_Shell;
158: snes->ops->view = SNESView_Shell;
159: snes->ops->solve = SNESSolve_Shell;
160: snes->ops->reset = SNESReset_Shell;
162: snes->usesksp = PETSC_FALSE;
163: snes->usesnpc = PETSC_FALSE;
165: snes->alwayscomputesfinalresidual = PETSC_FALSE;
167: PetscCall(PetscNew(&shell));
168: snes->data = (void *)shell;
169: PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
170: PetscFunctionReturn(PETSC_SUCCESS);
171: }