Actual source code: snesshell.c
1: #include <petsc/private/snesimpl.h>
3: typedef struct {
4: PetscErrorCode (*solve)(SNES, Vec);
5: PetscCtx 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 `SNESShellSetContext()`
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 SNESDestroy_Shell(SNES snes)
34: {
35: PetscFunctionBegin;
36: PetscCall(PetscFree(snes->data));
37: PetscFunctionReturn(PETSC_SUCCESS);
38: }
40: /*@
41: SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
43: Not Collective
45: Input Parameter:
46: . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
48: Output Parameter:
49: . ctx - the user provided context
51: Level: advanced
53: Fortran Notes:
54: This only works when the context is a Fortran derived type or a `PetscObject`. Declare `ctx` with
55: .vb
56: type(tUsertype), pointer :: ctx
57: .ve
59: .seealso: [](ch_snes), `SNES`, `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
60: @*/
61: PetscErrorCode SNESShellGetContext(SNES snes, PetscCtxRt ctx)
62: {
63: PetscBool flg;
65: PetscFunctionBegin;
67: PetscAssertPointer(ctx, 2);
68: PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
69: if (!flg) *(void **)ctx = NULL;
70: else *(void **)ctx = ((SNES_Shell *)snes->data)->ctx;
71: PetscFunctionReturn(PETSC_SUCCESS);
72: }
74: /*@
75: SNESShellSetContext - sets the context for a `SNESSHELL`
77: Logically Collective
79: Input Parameters:
80: + snes - the `SNESSHELL`
81: - ctx - the context
83: Level: advanced
85: .seealso: [](ch_snes), `SNES`, `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
86: @*/
87: PetscErrorCode SNESShellSetContext(SNES snes, PetscCtx ctx)
88: {
89: SNES_Shell *shell = (SNES_Shell *)snes->data;
90: PetscBool flg;
92: PetscFunctionBegin;
94: PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
95: if (flg) shell->ctx = ctx;
96: PetscFunctionReturn(PETSC_SUCCESS);
97: }
99: static PetscErrorCode SNESSolve_Shell(SNES snes)
100: {
101: SNES_Shell *shell = (SNES_Shell *)snes->data;
103: PetscFunctionBegin;
104: PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
105: snes->reason = SNES_CONVERGED_ITS;
106: PetscCall((*shell->solve)(snes, snes->vec_sol));
107: PetscFunctionReturn(PETSC_SUCCESS);
108: }
110: static PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
111: {
112: SNES_Shell *shell = (SNES_Shell *)snes->data;
114: PetscFunctionBegin;
115: shell->solve = solve;
116: PetscFunctionReturn(PETSC_SUCCESS);
117: }
119: /*MC
120: SNESSHELL - a user provided nonlinear solver
122: Level: advanced
124: .seealso: [](ch_snes), `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
125: M*/
127: PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
128: {
129: SNES_Shell *shell;
131: PetscFunctionBegin;
132: snes->ops->destroy = SNESDestroy_Shell;
133: snes->ops->solve = SNESSolve_Shell;
135: snes->usesksp = PETSC_FALSE;
136: snes->usesnpc = PETSC_FALSE;
138: snes->alwayscomputesfinalresidual = PETSC_FALSE;
140: PetscCall(SNESParametersInitialize(snes));
142: PetscCall(PetscNew(&shell));
143: snes->data = (void *)shell;
144: PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
145: PetscFunctionReturn(PETSC_SUCCESS);
146: }