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 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() 23 - xout - solution vector 24 25 Notes: 26 the function MUST return an error code of 0 on success and nonzero on failure. 27 28 Level: advanced 29 30 .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()` 31 @*/ 32 PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) { 33 PetscFunctionBegin; 34 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 35 PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve)); 36 PetscFunctionReturn(0); 37 } 38 39 PetscErrorCode SNESReset_Shell(SNES snes) { 40 PetscFunctionBegin; 41 PetscFunctionReturn(0); 42 } 43 44 PetscErrorCode SNESDestroy_Shell(SNES snes) { 45 PetscFunctionBegin; 46 PetscCall(SNESReset_Shell(snes)); 47 PetscCall(PetscFree(snes->data)); 48 PetscFunctionReturn(0); 49 } 50 51 PetscErrorCode SNESSetUp_Shell(SNES snes) { 52 PetscFunctionBegin; 53 PetscFunctionReturn(0); 54 } 55 56 PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject) { 57 PetscFunctionBegin; 58 PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options"); 59 PetscFunctionReturn(0); 60 } 61 62 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) { 63 PetscFunctionBegin; 64 PetscFunctionReturn(0); 65 } 66 67 /*@ 68 SNESShellGetContext - Returns the user-provided context associated with a shell SNES 69 70 Not Collective 71 72 Input Parameter: 73 . snes - should have been created with SNESSetType(snes,SNESSHELL); 74 75 Output Parameter: 76 . ctx - the user provided context 77 78 Level: advanced 79 80 Notes: 81 This routine is intended for use within various shell routines 82 83 .seealso: `SNESCreateShell()`, `SNESShellSetContext()` 84 @*/ 85 PetscErrorCode SNESShellGetContext(SNES snes, void *ctx) { 86 PetscBool flg; 87 88 PetscFunctionBegin; 89 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 90 PetscValidPointer(ctx, 2); 91 PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg)); 92 if (!flg) *(void **)ctx = NULL; 93 else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx; 94 PetscFunctionReturn(0); 95 } 96 97 /*@ 98 SNESShellSetContext - sets the context for a shell SNES 99 100 Logically Collective on SNES 101 102 Input Parameters: 103 + snes - the shell SNES 104 - ctx - the context 105 106 Level: advanced 107 108 Fortran Notes: 109 The context can only be an integer or a PetscObject 110 unfortunately it cannot be a Fortran array or derived type. 111 112 .seealso: `SNESCreateShell()`, `SNESShellGetContext()` 113 @*/ 114 PetscErrorCode SNESShellSetContext(SNES snes, void *ctx) { 115 SNES_Shell *shell = (SNES_Shell *)snes->data; 116 PetscBool flg; 117 118 PetscFunctionBegin; 119 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 120 PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg)); 121 if (flg) shell->ctx = ctx; 122 PetscFunctionReturn(0); 123 } 124 125 PetscErrorCode SNESSolve_Shell(SNES snes) { 126 SNES_Shell *shell = (SNES_Shell *)snes->data; 127 128 PetscFunctionBegin; 129 PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first"); 130 snes->reason = SNES_CONVERGED_ITS; 131 PetscCall((*shell->solve)(snes, snes->vec_sol)); 132 PetscFunctionReturn(0); 133 } 134 135 PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) { 136 SNES_Shell *shell = (SNES_Shell *)snes->data; 137 138 PetscFunctionBegin; 139 shell->solve = solve; 140 PetscFunctionReturn(0); 141 } 142 143 /*MC 144 SNESSHELL - a user provided nonlinear solver 145 146 Level: advanced 147 148 .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType` 149 M*/ 150 151 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) { 152 SNES_Shell *shell; 153 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; 161 162 snes->usesksp = PETSC_FALSE; 163 snes->usesnpc = PETSC_FALSE; 164 165 snes->alwayscomputesfinalresidual = PETSC_FALSE; 166 167 PetscCall(PetscNewLog(snes, &shell)); 168 snes->data = (void *)shell; 169 PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell)); 170 PetscFunctionReturn(0); 171 } 172