1 #include <petsc/private/linesearchimpl.h> 2 #include <petsc/private/snesimpl.h> 3 4 typedef struct { 5 SNESLineSearchUserFunc func; 6 void *ctx; 7 } SNESLineSearch_Shell; 8 9 /*@C 10 SNESLineSearchShellSetUserFunc - Sets the user function for the `SNESLINESEARCHSHELL` implementation. 11 12 Not Collective 13 14 Input Parameters: 15 + linesearch - `SNESLineSearch` context 16 . func - function implementing the linesearch shell. 17 - ctx - context for func 18 19 Calling sequence of func: 20 + linesearch - the linesearch instance 21 - ctx - the above mentioned context 22 23 Usage: 24 $ PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx) 25 $ { 26 $ Vec X,Y,F,W,G; 27 $ SNES snes; 28 $ PetscFunctionBegin; 29 $ PetscCall(SNESLineSearchGetSNES(linesearch,&snes)); 30 $ PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED)); 31 $ PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G)); 32 $ .. determine lambda using W and G as work vecs.. 33 $ PetscCall(VecAXPY(X,-lambda,Y)); 34 $ PetscCall(SNESComputeFunction(snes,X,F)); 35 $ PetscCall(SNESLineSearchComputeNorms(linesearch)); 36 $ PetscFunctionReturn(0); 37 $ } 38 $ 39 $ ... 40 $ 41 $ PetscCall(SNESGetLineSearch(snes, &linesearch)); 42 $ PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL)); 43 $ PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL)); 44 45 Level: advanced 46 47 .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch` 48 @*/ 49 PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) 50 { 51 PetscBool flg; 52 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 53 54 PetscFunctionBegin; 55 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 56 PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 57 if (flg) { 58 shell->ctx = ctx; 59 shell->func = func; 60 } 61 PetscFunctionReturn(0); 62 } 63 64 /*@C 65 SNESLineSearchShellGetUserFunc - Gets the user function and context for the `SNESLINESEARCHSHELL` 66 67 Not Collective 68 69 Input Parameter: 70 . linesearch - the line search object 71 72 Output Parameters: 73 + func - the user function; can be NULL if you do not want it 74 - ctx - the user function context; can be NULL if you do not want it 75 76 Level: advanced 77 78 .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch` 79 @*/ 80 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) 81 { 82 PetscBool flg; 83 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 84 85 PetscFunctionBegin; 86 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 87 if (func) PetscValidPointer(func, 2); 88 if (ctx) PetscValidPointer(ctx, 3); 89 PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 90 if (flg) { 91 if (func) *func = shell->func; 92 if (ctx) *ctx = shell->ctx; 93 } 94 PetscFunctionReturn(0); 95 } 96 97 static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 98 { 99 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 100 101 PetscFunctionBegin; 102 /* apply the user function */ 103 if (shell->func) { 104 PetscCall((*shell->func)(linesearch, shell->ctx)); 105 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 106 PetscFunctionReturn(0); 107 } 108 109 static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 110 { 111 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 112 113 PetscFunctionBegin; 114 PetscCall(PetscFree(shell)); 115 PetscFunctionReturn(0); 116 } 117 118 /*MC 119 SNESLINESEARCHSHELL - Provides context for a user-provided line search routine. 120 121 The user routine has one argument, the SNESLineSearch context. The user uses the interface to 122 extract line search parameters and set them accordingly when the computation is finished. 123 124 Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 125 template in the documentation for SNESLineSearchShellSetUserFunc(). 126 127 Level: advanced 128 129 .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()` 130 M*/ 131 PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 132 { 133 SNESLineSearch_Shell *shell; 134 135 PetscFunctionBegin; 136 linesearch->ops->apply = SNESLineSearchApply_Shell; 137 linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 138 linesearch->ops->setfromoptions = NULL; 139 linesearch->ops->reset = NULL; 140 linesearch->ops->view = NULL; 141 linesearch->ops->setup = NULL; 142 143 PetscCall(PetscNew(&shell)); 144 145 linesearch->data = (void *)shell; 146 PetscFunctionReturn(0); 147 } 148