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