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