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