1 #include <petsc-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);CHKERRQ(ierr); 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 /*@ 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 = PetscObjectTypeCompare((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 = PetscObjectTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr); 153 if (flg) shell->ctx = ctx; 154 PetscFunctionReturn(0); 155 } 156 157 #undef __FUNCT__ 158 #define __FUNCT__ "SNESSolve_Shell" 159 PetscErrorCode SNESSolve_Shell(SNES snes) 160 { 161 SNES_Shell *shell = (SNES_Shell*) snes->data; 162 PetscErrorCode ierr; 163 164 PetscFunctionBegin; 165 if (!shell->solve) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first"); 166 snes->reason = SNES_CONVERGED_ITS; 167 ierr = (*shell->solve)(snes,snes->vec_sol);CHKERRQ(ierr); 168 PetscFunctionReturn(0); 169 } 170 171 #undef __FUNCT__ 172 #define __FUNCT__ "SNESShellSetSolve_Shell" 173 PetscErrorCode SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec)) 174 { 175 SNES_Shell *shell = (SNES_Shell*)snes->data; 176 177 PetscFunctionBegin; 178 shell->solve = solve; 179 PetscFunctionReturn(0); 180 } 181 182 /*MC 183 SNESSHELL - a user provided nonlinear solver 184 185 Level: advanced 186 187 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types) 188 M*/ 189 190 #undef __FUNCT__ 191 #define __FUNCT__ "SNESCreate_Shell" 192 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) 193 { 194 SNES_Shell *shell; 195 PetscErrorCode ierr; 196 197 PetscFunctionBegin; 198 snes->ops->destroy = SNESDestroy_Shell; 199 snes->ops->setup = SNESSetUp_Shell; 200 snes->ops->setfromoptions = SNESSetFromOptions_Shell; 201 snes->ops->view = SNESView_Shell; 202 snes->ops->solve = SNESSolve_Shell; 203 snes->ops->reset = SNESReset_Shell; 204 205 snes->usesksp = PETSC_FALSE; 206 snes->usespc = PETSC_FALSE; 207 208 ierr = PetscNewLog(snes, SNES_Shell, &shell);CHKERRQ(ierr); 209 snes->data = (void*) shell; 210 ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESShellSetSolve_C",SNESShellSetSolve_Shell);CHKERRQ(ierr); 211 PetscFunctionReturn(0); 212 } 213