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