1 #include <private/snesimpl.h> 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 SNES_Shell *shell = (SNES_Shell*) snes->data; 47 48 PetscFunctionBegin; 49 PetscFunctionReturn(0); 50 } 51 52 #undef __FUNCT__ 53 #define __FUNCT__ "SNESDestroy_Shell" 54 PetscErrorCode SNESDestroy_Shell(SNES snes) 55 { 56 PetscErrorCode ierr; 57 58 PetscFunctionBegin; 59 ierr = SNESReset_Shell(snes);CHKERRQ(ierr); 60 ierr = PetscFree(snes->data); 61 PetscFunctionReturn(0); 62 } 63 64 #undef __FUNCT__ 65 #define __FUNCT__ "SNESSetUp_Shell" 66 PetscErrorCode SNESSetUp_Shell(SNES snes) 67 { 68 SNES_Shell *shell = (SNES_Shell *) snes->data; 69 70 PetscFunctionBegin; 71 PetscFunctionReturn(0); 72 } 73 74 #undef __FUNCT__ 75 #define __FUNCT__ "SNESSetFromOptions_Shell" 76 PetscErrorCode SNESSetFromOptions_Shell(SNES snes) 77 { 78 SNES_Shell *shell = (SNES_Shell *) snes->data; 79 PetscErrorCode ierr; 80 81 PetscFunctionBegin; 82 ierr = PetscOptionsHead("SNES Shell options");CHKERRQ(ierr); 83 PetscFunctionReturn(0); 84 } 85 86 #undef __FUNCT__ 87 #define __FUNCT__ "SNESView_Shell" 88 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) 89 { 90 SNES_Shell *shell = (SNES_Shell *) snes->data; 91 92 PetscFunctionBegin; 93 PetscFunctionReturn(0); 94 } 95 96 #undef __FUNCT__ 97 #define __FUNCT__ "SNESShellGetContext" 98 /*@C 99 SNESShellGetContext - Returns the user-provided context associated with a shell SNES 100 101 Not Collective 102 103 Input Parameter: 104 . snes - should have been created with SNESSetType(snes,SNESSHELL); 105 106 Output Parameter: 107 . ctx - the user provided context 108 109 Level: advanced 110 111 Notes: 112 This routine is intended for use within various shell routines 113 114 .keywords: SNES, shell, get, context 115 116 .seealso: SNESCreateShell(), SNESShellSetContext() 117 @*/ 118 PetscErrorCode SNESShellGetContext(SNES snes,void **ctx) 119 { 120 PetscErrorCode ierr; 121 PetscBool flg; 122 123 PetscFunctionBegin; 124 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 125 PetscValidPointer(ctx,2); 126 ierr = PetscTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr); 127 if (!flg) *ctx = 0; 128 else *ctx = ((SNES_Shell*)(snes->data))->ctx; 129 PetscFunctionReturn(0); 130 } 131 132 #undef __FUNCT__ 133 #define __FUNCT__ "SNESShellSetContext" 134 /*@ 135 SNESShellSetContext - sets the context for a shell SNES 136 137 Logically Collective on SNES 138 139 Input Parameters: 140 + snes - the shell SNES 141 - ctx - the context 142 143 Level: advanced 144 145 Fortran Notes: The context can only be an integer or a PetscObject 146 unfortunately it cannot be a Fortran array or derived type. 147 148 149 .seealso: SNESCreateShell(), SNESShellGetContext() 150 @*/ 151 PetscErrorCode SNESShellSetContext(SNES snes,void *ctx) 152 { 153 SNES_Shell *shell = (SNES_Shell*)snes->data; 154 PetscErrorCode ierr; 155 PetscBool flg; 156 157 PetscFunctionBegin; 158 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 159 ierr = PetscTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr); 160 if (flg) { 161 shell->ctx = ctx; 162 } 163 PetscFunctionReturn(0); 164 } 165 166 #undef __FUNCT__ 167 #define __FUNCT__ "SNESSolve_Shell" 168 PetscErrorCode SNESSolve_Shell(SNES snes) 169 { 170 SNES_Shell *shell = (SNES_Shell *) snes->data; 171 PetscErrorCode ierr; 172 173 PetscFunctionBegin; 174 if (!shell->solve) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first"); 175 ierr = (*shell->solve)(snes,snes->vec_sol);CHKERRQ(ierr); 176 PetscFunctionReturn(0); 177 } 178 179 EXTERN_C_BEGIN 180 #undef __FUNCT__ 181 #define __FUNCT__ "SNESShellSetSolve_Shell" 182 PetscErrorCode SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec)) 183 { 184 SNES_Shell *shell = (SNES_Shell*)snes->data; 185 186 PetscFunctionBegin; 187 shell->solve = solve; 188 PetscFunctionReturn(0); 189 } 190 EXTERN_C_END 191 192 /*MC 193 SNESSHELL - a user provided nonlinear solver 194 195 Level: advanced 196 197 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types) 198 M*/ 199 200 EXTERN_C_BEGIN 201 #undef __FUNCT__ 202 #define __FUNCT__ "SNESCreate_Shell" 203 PetscErrorCode SNESCreate_Shell(SNES snes) 204 { 205 SNES_Shell *shell; 206 PetscErrorCode ierr; 207 208 PetscFunctionBegin; 209 snes->ops->destroy = SNESDestroy_Shell; 210 snes->ops->setup = SNESSetUp_Shell; 211 snes->ops->setfromoptions = SNESSetFromOptions_Shell; 212 snes->ops->view = SNESView_Shell; 213 snes->ops->solve = SNESSolve_Shell; 214 snes->ops->reset = SNESReset_Shell; 215 216 snes->usesksp = PETSC_FALSE; 217 218 ierr = PetscNewLog(snes, SNES_Shell, &shell);CHKERRQ(ierr); 219 snes->data = (void*) shell; 220 ierr = PetscObjectComposeFunctionDynamic((PetscObject)snes,"SNESShellSetSolve_C","SNESShellSetSolve_Shell",SNESShellSetSolve_Shell);CHKERRQ(ierr); 221 PetscFunctionReturn(0); 222 } 223 EXTERN_C_END 224