1 #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 2 3 typedef struct {PetscErrorCode (*solve)(SNES,Vec);void *ctx;} SNES_Shell; 4 5 /*@C 6 SNESShellSetSolve - Sets routine to apply as solver 7 8 Logically Collective on SNES 9 10 Input Parameters: 11 + snes - the nonlinear solver context 12 - apply - the application-provided solver routine 13 14 Calling sequence of solve: 15 .vb 16 PetscErrorCode apply (SNES snes,Vec xout) 17 .ve 18 19 + snes - the preconditioner, get the application context with SNESShellGetContext() 20 - xout - solution vector 21 22 Notes: 23 the function MUST return an error code of 0 on success and nonzero on failure. 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 CHKERRQ(PetscTryMethod(snes,"SNESShellSetSolve_C",(SNES,PetscErrorCode (*)(SNES,Vec)),(snes,solve))); 34 PetscFunctionReturn(0); 35 } 36 37 PetscErrorCode SNESReset_Shell(SNES snes) 38 { 39 PetscFunctionBegin; 40 PetscFunctionReturn(0); 41 } 42 43 PetscErrorCode SNESDestroy_Shell(SNES snes) 44 { 45 PetscFunctionBegin; 46 CHKERRQ(SNESReset_Shell(snes)); 47 CHKERRQ(PetscFree(snes->data)); 48 PetscFunctionReturn(0); 49 } 50 51 PetscErrorCode SNESSetUp_Shell(SNES snes) 52 { 53 PetscFunctionBegin; 54 PetscFunctionReturn(0); 55 } 56 57 PetscErrorCode SNESSetFromOptions_Shell(PetscOptionItems *PetscOptionsObject,SNES snes) 58 { 59 PetscFunctionBegin; 60 CHKERRQ(PetscOptionsHead(PetscOptionsObject,"SNES Shell options")); 61 PetscFunctionReturn(0); 62 } 63 64 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) 65 { 66 PetscFunctionBegin; 67 PetscFunctionReturn(0); 68 } 69 70 /*@ 71 SNESShellGetContext - Returns the user-provided context associated with a shell SNES 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 Notes: 84 This routine is intended for use within various shell routines 85 86 .seealso: SNESCreateShell(), SNESShellSetContext() 87 @*/ 88 PetscErrorCode SNESShellGetContext(SNES snes,void *ctx) 89 { 90 PetscBool flg; 91 92 PetscFunctionBegin; 93 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 94 PetscValidPointer(ctx,2); 95 CHKERRQ(PetscObjectTypeCompare((PetscObject)snes,SNESSHELL,&flg)); 96 if (!flg) *(void**)ctx = NULL; 97 else *(void**)ctx = ((SNES_Shell*)(snes->data))->ctx; 98 PetscFunctionReturn(0); 99 } 100 101 /*@ 102 SNESShellSetContext - sets the context for a shell SNES 103 104 Logically Collective on SNES 105 106 Input Parameters: 107 + snes - the shell SNES 108 - ctx - the context 109 110 Level: advanced 111 112 Fortran Notes: 113 The context can only be an integer or a PetscObject 114 unfortunately it cannot be a Fortran array or derived type. 115 116 .seealso: SNESCreateShell(), SNESShellGetContext() 117 @*/ 118 PetscErrorCode SNESShellSetContext(SNES snes,void *ctx) 119 { 120 SNES_Shell *shell = (SNES_Shell*)snes->data; 121 PetscBool flg; 122 123 PetscFunctionBegin; 124 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 125 CHKERRQ(PetscObjectTypeCompare((PetscObject)snes,SNESSHELL,&flg)); 126 if (flg) shell->ctx = ctx; 127 PetscFunctionReturn(0); 128 } 129 130 PetscErrorCode SNESSolve_Shell(SNES snes) 131 { 132 SNES_Shell *shell = (SNES_Shell*) snes->data; 133 134 PetscFunctionBegin; 135 PetscCheckFalse(!shell->solve,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first"); 136 snes->reason = SNES_CONVERGED_ITS; 137 CHKERRQ((*shell->solve)(snes,snes->vec_sol)); 138 PetscFunctionReturn(0); 139 } 140 141 PetscErrorCode SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec)) 142 { 143 SNES_Shell *shell = (SNES_Shell*)snes->data; 144 145 PetscFunctionBegin; 146 shell->solve = solve; 147 PetscFunctionReturn(0); 148 } 149 150 /*MC 151 SNESSHELL - a user provided nonlinear solver 152 153 Level: advanced 154 155 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types) 156 M*/ 157 158 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) 159 { 160 SNES_Shell *shell; 161 162 PetscFunctionBegin; 163 snes->ops->destroy = SNESDestroy_Shell; 164 snes->ops->setup = SNESSetUp_Shell; 165 snes->ops->setfromoptions = SNESSetFromOptions_Shell; 166 snes->ops->view = SNESView_Shell; 167 snes->ops->solve = SNESSolve_Shell; 168 snes->ops->reset = SNESReset_Shell; 169 170 snes->usesksp = PETSC_FALSE; 171 snes->usesnpc = PETSC_FALSE; 172 173 snes->alwayscomputesfinalresidual = PETSC_FALSE; 174 175 CHKERRQ(PetscNewLog(snes,&shell)); 176 snes->data = (void*) shell; 177 CHKERRQ(PetscObjectComposeFunction((PetscObject)snes,"SNESShellSetSolve_C",SNESShellSetSolve_Shell)); 178 PetscFunctionReturn(0); 179 } 180