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