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: }