1 #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 2 3 typedef struct {PetscErrorCode (*solve)(SNES,Vec);void *ctx;} SNES_Shell; 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "SNESShellSetSolve" 7 /*@C 8 SNESShellSetSolve - Sets routine to apply as solver 9 10 Logically Collective on SNES 11 12 Input Parameters: 13 + snes - the nonlinear solver context 14 - apply - the application-provided solver routine 15 16 Calling sequence of solve: 17 .vb 18 PetscErrorCode apply (SNES snes,Vec xout) 19 .ve 20 21 + snes - the preconditioner, get the application context with SNESShellGetContext() 22 - xout - solution vector 23 24 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 25 26 Level: advanced 27 28 .keywords: SNES, shell, set, apply, user-provided 29 30 .seealso: SNESSHELL, SNESShellSetContext(), SNESShellGetContext() 31 @*/ 32 PetscErrorCode SNESShellSetSolve(SNES snes,PetscErrorCode (*solve)(SNES,Vec)) 33 { 34 PetscErrorCode ierr; 35 36 PetscFunctionBegin; 37 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38 ierr = PetscTryMethod(snes,"SNESShellSetSolve_C",(SNES,PetscErrorCode (*)(SNES,Vec)),(snes,solve));CHKERRQ(ierr); 39 PetscFunctionReturn(0); 40 } 41 42 #undef __FUNCT__ 43 #define __FUNCT__ "SNESReset_Shell" 44 PetscErrorCode SNESReset_Shell(SNES snes) 45 { 46 PetscFunctionBegin; 47 PetscFunctionReturn(0); 48 } 49 50 #undef __FUNCT__ 51 #define __FUNCT__ "SNESDestroy_Shell" 52 PetscErrorCode SNESDestroy_Shell(SNES snes) 53 { 54 PetscErrorCode ierr; 55 56 PetscFunctionBegin; 57 ierr = SNESReset_Shell(snes);CHKERRQ(ierr); 58 ierr = PetscFree(snes->data); 59 PetscFunctionReturn(0); 60 } 61 62 #undef __FUNCT__ 63 #define __FUNCT__ "SNESSetUp_Shell" 64 PetscErrorCode SNESSetUp_Shell(SNES snes) 65 { 66 PetscFunctionBegin; 67 PetscFunctionReturn(0); 68 } 69 70 #undef __FUNCT__ 71 #define __FUNCT__ "SNESSetFromOptions_Shell" 72 PetscErrorCode SNESSetFromOptions_Shell(SNES snes) 73 { 74 PetscErrorCode ierr; 75 76 PetscFunctionBegin; 77 ierr = PetscOptionsHead("SNES Shell options");CHKERRQ(ierr); 78 PetscFunctionReturn(0); 79 } 80 81 #undef __FUNCT__ 82 #define __FUNCT__ "SNESView_Shell" 83 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) 84 { 85 PetscFunctionBegin; 86 PetscFunctionReturn(0); 87 } 88 89 #undef __FUNCT__ 90 #define __FUNCT__ "SNESShellGetContext" 91 /*@C 92 SNESShellGetContext - Returns the user-provided context associated with a shell SNES 93 94 Not Collective 95 96 Input Parameter: 97 . snes - should have been created with SNESSetType(snes,SNESSHELL); 98 99 Output Parameter: 100 . ctx - the user provided context 101 102 Level: advanced 103 104 Notes: 105 This routine is intended for use within various shell routines 106 107 .keywords: SNES, shell, get, context 108 109 .seealso: SNESCreateShell(), SNESShellSetContext() 110 @*/ 111 PetscErrorCode SNESShellGetContext(SNES snes,void **ctx) 112 { 113 PetscErrorCode ierr; 114 PetscBool flg; 115 116 PetscFunctionBegin; 117 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 118 PetscValidPointer(ctx,2); 119 ierr = PetscTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr); 120 if (!flg) *ctx = 0; 121 else *ctx = ((SNES_Shell*)(snes->data))->ctx; 122 PetscFunctionReturn(0); 123 } 124 125 #undef __FUNCT__ 126 #define __FUNCT__ "SNESShellSetContext" 127 /*@ 128 SNESShellSetContext - sets the context for a shell SNES 129 130 Logically Collective on SNES 131 132 Input Parameters: 133 + snes - the shell SNES 134 - ctx - the context 135 136 Level: advanced 137 138 Fortran Notes: The context can only be an integer or a PetscObject 139 unfortunately it cannot be a Fortran array or derived type. 140 141 142 .seealso: SNESCreateShell(), SNESShellGetContext() 143 @*/ 144 PetscErrorCode SNESShellSetContext(SNES snes,void *ctx) 145 { 146 SNES_Shell *shell = (SNES_Shell*)snes->data; 147 PetscErrorCode ierr; 148 PetscBool flg; 149 150 PetscFunctionBegin; 151 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 152 ierr = PetscTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr); 153 if (flg) { 154 shell->ctx = ctx; 155 } 156 PetscFunctionReturn(0); 157 } 158 159 #undef __FUNCT__ 160 #define __FUNCT__ "SNESSolve_Shell" 161 PetscErrorCode SNESSolve_Shell(SNES snes) 162 { 163 SNES_Shell *shell = (SNES_Shell *) snes->data; 164 PetscErrorCode ierr; 165 166 PetscFunctionBegin; 167 if (!shell->solve) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first"); 168 snes->reason = SNES_CONVERGED_ITS; 169 ierr = (*shell->solve)(snes,snes->vec_sol);CHKERRQ(ierr); 170 PetscFunctionReturn(0); 171 } 172 173 EXTERN_C_BEGIN 174 #undef __FUNCT__ 175 #define __FUNCT__ "SNESShellSetSolve_Shell" 176 PetscErrorCode SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec)) 177 { 178 SNES_Shell *shell = (SNES_Shell*)snes->data; 179 180 PetscFunctionBegin; 181 shell->solve = solve; 182 PetscFunctionReturn(0); 183 } 184 EXTERN_C_END 185 186 /*MC 187 SNESSHELL - a user provided nonlinear solver 188 189 Level: advanced 190 191 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types) 192 M*/ 193 194 EXTERN_C_BEGIN 195 #undef __FUNCT__ 196 #define __FUNCT__ "SNESCreate_Shell" 197 PetscErrorCode SNESCreate_Shell(SNES snes) 198 { 199 SNES_Shell *shell; 200 PetscErrorCode ierr; 201 202 PetscFunctionBegin; 203 snes->ops->destroy = SNESDestroy_Shell; 204 snes->ops->setup = SNESSetUp_Shell; 205 snes->ops->setfromoptions = SNESSetFromOptions_Shell; 206 snes->ops->view = SNESView_Shell; 207 snes->ops->solve = SNESSolve_Shell; 208 snes->ops->reset = SNESReset_Shell; 209 210 snes->usesksp = PETSC_FALSE; 211 snes->usespc = PETSC_FALSE; 212 213 ierr = PetscNewLog(snes, SNES_Shell, &shell);CHKERRQ(ierr); 214 snes->data = (void*) shell; 215 ierr = PetscObjectComposeFunctionDynamic((PetscObject)snes,"SNESShellSetSolve_C","SNESShellSetSolve_Shell",SNESShellSetSolve_Shell);CHKERRQ(ierr); 216 PetscFunctionReturn(0); 217 } 218 EXTERN_C_END 219