1 #include <petsc/private/linesearchimpl.h> 2 #include <petsc/private/snesimpl.h> 3 4 typedef struct { 5 SNESLineSearchShellApplyFn *func; 6 void *ctx; 7 } SNESLineSearch_Shell; 8 9 // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation 10 /*@C 11 SNESLineSearchShellSetApply - Sets the apply function for the `SNESLINESEARCHSHELL` implementation. 12 13 Not Collective 14 15 Input Parameters: 16 + linesearch - `SNESLineSearch` context 17 . func - function implementing the linesearch shell, see `SNESLineSearchShellApplyFn` for calling sequence 18 - ctx - context for func 19 20 Usage\: 21 .vb 22 PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx) 23 { 24 Vec X,Y,F,W,G; 25 SNES snes; 26 27 PetscFunctionBegin; 28 PetscCall(SNESLineSearchGetSNES(linesearch,&snes)); 29 PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED)); 30 PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G)); 31 // determine lambda using W and G as work vecs.. 32 PetscCall(VecAXPY(X,-lambda,Y)); 33 PetscCall(SNESComputeFunction(snes,X,F)); 34 PetscCall(SNESLineSearchComputeNorms(linesearch)); 35 PetscFunctionReturn(PETSC_SUCCESS); 36 } 37 38 PetscCall(SNESGetLineSearch(snes, &linesearch)); 39 PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL)); 40 PetscCall(SNESLineSearchShellSetApply(linesearch, shellfunc, NULL)); 41 .ve 42 43 Level: advanced 44 45 .seealso: [](ch_snes), `SNESLineSearchShellGetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`, 46 `SNESLineSearchShellApplyFn` 47 @*/ 48 PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn *func, void *ctx) 49 { 50 PetscBool flg; 51 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 52 53 PetscFunctionBegin; 54 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 55 PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 56 if (flg) { 57 shell->ctx = ctx; 58 shell->func = func; 59 } 60 PetscFunctionReturn(PETSC_SUCCESS); 61 } 62 63 /*@C 64 SNESLineSearchShellGetApply - Gets the apply function and context for the `SNESLINESEARCHSHELL` 65 66 Not Collective 67 68 Input Parameter: 69 . linesearch - the line search object 70 71 Output Parameters: 72 + func - the user function; can be `NULL` if it is not needed, see `SNESLineSearchShellApplyFn` for calling sequence 73 - ctx - the user function context; can be `NULL` if it is not needed 74 75 Level: advanced 76 77 .seealso: [](ch_snes), `SNESLineSearchShellSetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`, 78 `SNESLineSearchShellApplyFn` 79 @*/ 80 PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn **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) PetscAssertPointer(func, 2); 88 if (ctx) PetscAssertPointer(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(PETSC_SUCCESS); 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 PetscCheck(shell->func, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()"); 104 PetscCall((*shell->func)(linesearch, shell->ctx)); 105 PetscFunctionReturn(PETSC_SUCCESS); 106 } 107 108 static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 109 { 110 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 111 112 PetscFunctionBegin; 113 PetscCall(PetscFree(shell)); 114 PetscFunctionReturn(PETSC_SUCCESS); 115 } 116 117 /*MC 118 SNESLINESEARCHSHELL - Provides an API for a user-provided line search routine. 119 120 Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 121 template in the documentation for `SNESLineSearchShellSetApply()`. 122 123 Level: advanced 124 125 .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`, 126 `SNESLineSearchShellApplyFn` 127 M*/ 128 129 PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 130 { 131 SNESLineSearch_Shell *shell; 132 133 PetscFunctionBegin; 134 linesearch->ops->apply = SNESLineSearchApply_Shell; 135 linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 136 linesearch->ops->setfromoptions = NULL; 137 linesearch->ops->reset = NULL; 138 linesearch->ops->view = NULL; 139 linesearch->ops->setup = NULL; 140 141 PetscCall(PetscNew(&shell)); 142 143 linesearch->data = (void *)shell; 144 PetscFunctionReturn(PETSC_SUCCESS); 145 } 146