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