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