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