Date: 2025-03-28T21:11:07+00:00

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 `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 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(SNESParametersInitialize(snes));

    169:   PetscCall(PetscNew(&shell));
    170:   snes->data = (void *)shell;
    171:   PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
    172:   PetscFunctionReturn(PETSC_SUCCESS);
    173: }