1 #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 2 3 typedef struct { 4 PetscErrorCode (*solve)(SNES, Vec); 5 void *ctx; 6 } SNES_Shell; 7 8 /*@C 9 SNESShellSetSolve - Sets routine to apply as solver 10 11 Logically Collective on snes 12 13 Input Parameters: 14 + snes - the `SNES` nonlinear solver context 15 - apply - the application-provided solver routine 16 17 Calling sequence of solve: 18 .vb 19 PetscErrorCode apply (SNES snes,Vec xout) 20 .ve 21 22 + snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()` 23 - xout - solution vector 24 25 Level: advanced 26 27 .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()` 28 @*/ 29 PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) { 30 PetscFunctionBegin; 31 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 32 PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve)); 33 PetscFunctionReturn(0); 34 } 35 36 PetscErrorCode SNESReset_Shell(SNES snes) { 37 PetscFunctionBegin; 38 PetscFunctionReturn(0); 39 } 40 41 PetscErrorCode SNESDestroy_Shell(SNES snes) { 42 PetscFunctionBegin; 43 PetscCall(SNESReset_Shell(snes)); 44 PetscCall(PetscFree(snes->data)); 45 PetscFunctionReturn(0); 46 } 47 48 PetscErrorCode SNESSetUp_Shell(SNES snes) { 49 PetscFunctionBegin; 50 PetscFunctionReturn(0); 51 } 52 53 PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject) { 54 PetscFunctionBegin; 55 PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options"); 56 PetscFunctionReturn(0); 57 } 58 59 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) { 60 PetscFunctionBegin; 61 PetscFunctionReturn(0); 62 } 63 64 /*@ 65 SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL` 66 67 Not Collective 68 69 Input Parameter: 70 . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`); 71 72 Output Parameter: 73 . ctx - the user provided context 74 75 Level: advanced 76 77 .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()` 78 @*/ 79 PetscErrorCode SNESShellGetContext(SNES snes, void *ctx) { 80 PetscBool flg; 81 82 PetscFunctionBegin; 83 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 84 PetscValidPointer(ctx, 2); 85 PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg)); 86 if (!flg) *(void **)ctx = NULL; 87 else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx; 88 PetscFunctionReturn(0); 89 } 90 91 /*@ 92 SNESShellSetContext - sets the context for a `SNESSHELL` 93 94 Logically Collective on snes 95 96 Input Parameters: 97 + snes - the `SNESSHELL` 98 - ctx - the context 99 100 Level: advanced 101 102 Fortran Note: 103 The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type. 104 105 .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()` 106 @*/ 107 PetscErrorCode SNESShellSetContext(SNES snes, void *ctx) { 108 SNES_Shell *shell = (SNES_Shell *)snes->data; 109 PetscBool flg; 110 111 PetscFunctionBegin; 112 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 113 PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg)); 114 if (flg) shell->ctx = ctx; 115 PetscFunctionReturn(0); 116 } 117 118 PetscErrorCode SNESSolve_Shell(SNES snes) { 119 SNES_Shell *shell = (SNES_Shell *)snes->data; 120 121 PetscFunctionBegin; 122 PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first"); 123 snes->reason = SNES_CONVERGED_ITS; 124 PetscCall((*shell->solve)(snes, snes->vec_sol)); 125 PetscFunctionReturn(0); 126 } 127 128 PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) { 129 SNES_Shell *shell = (SNES_Shell *)snes->data; 130 131 PetscFunctionBegin; 132 shell->solve = solve; 133 PetscFunctionReturn(0); 134 } 135 136 /*MC 137 SNESSHELL - a user provided nonlinear solver 138 139 Level: advanced 140 141 .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()` 142 M*/ 143 144 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) { 145 SNES_Shell *shell; 146 147 PetscFunctionBegin; 148 snes->ops->destroy = SNESDestroy_Shell; 149 snes->ops->setup = SNESSetUp_Shell; 150 snes->ops->setfromoptions = SNESSetFromOptions_Shell; 151 snes->ops->view = SNESView_Shell; 152 snes->ops->solve = SNESSolve_Shell; 153 snes->ops->reset = SNESReset_Shell; 154 155 snes->usesksp = PETSC_FALSE; 156 snes->usesnpc = PETSC_FALSE; 157 158 snes->alwayscomputesfinalresidual = PETSC_FALSE; 159 160 PetscCall(PetscNew(&shell)); 161 snes->data = (void *)shell; 162 PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell)); 163 PetscFunctionReturn(0); 164 } 165