1 #include <petsc/private/linesearchimpl.h> 2 #include <petsc/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 $ { 30 $ Vec X,Y,F,W,G; 31 $ SNES snes; 32 $ PetscFunctionBegin; 33 $ ierr = SNESLineSearchGetSNES(linesearch,&snes);CHKERRQ(ierr); 34 $ ierr = SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED);CHKERRQ(ierr); 35 $ ierr = SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G);CHKERRQ(ierr); 36 $ .. determine lambda using W and G as work vecs.. 37 $ ierr = VecAXPY(X,-lambda,Y);CHKERRQ(ierr); 38 $ ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 39 $ ierr = SNESLineSearchComputeNorms(linesearch);CHKERRQ(ierr); 40 $ PetscFunctionReturn(0); 41 $ } 42 $ 43 $ ... 44 $ 45 $ ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 46 $ ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL);CHKERRQ(ierr); 47 $ ierr = SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL);CHKERRQ(ierr); 48 49 Level: advanced 50 51 .keywords: SNESLineSearch, Shell, user, function, set 52 53 .seealso: SNESLineSearchShellGetUserFunc(), SNESLINESEARCHSHELL 54 @*/ 55 PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) 56 { 57 PetscErrorCode ierr; 58 PetscBool flg; 59 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 60 61 PetscFunctionBegin; 62 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 63 ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr); 64 if (flg) { 65 shell->ctx = ctx; 66 shell->func = func; 67 } 68 PetscFunctionReturn(0); 69 } 70 71 72 #undef __FUNCT__ 73 #define __FUNCT__ "SNESLineSearchShellGetUserFunc" 74 /*@C 75 SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation. 76 77 Not Collective 78 79 Input Parameter: 80 . linesearch - the line search object 81 82 Output Parameters: 83 + func - the user function; can be NULL if you do not want it 84 - ctx - the user function context; can be NULL if you do not want it 85 86 Level: advanced 87 88 .keywords: SNESLineSearch, get, Shell, user, function 89 90 .seealso: SNESLineSearchShellSetUserFunc() 91 @*/ 92 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) 93 { 94 PetscErrorCode ierr; 95 PetscBool flg; 96 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 97 98 PetscFunctionBegin; 99 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 100 if (func) PetscValidPointer(func,2); 101 if (ctx) PetscValidPointer(ctx,3); 102 ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr); 103 if (flg) { 104 if (func) *func = shell->func; 105 if (ctx) *ctx = shell->ctx; 106 } 107 PetscFunctionReturn(0); 108 } 109 110 111 #undef __FUNCT__ 112 #define __FUNCT__ "SNESLineSearchApply_Shell" 113 static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 114 { 115 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 116 PetscErrorCode ierr; 117 118 PetscFunctionBegin; 119 /* apply the user function */ 120 if (shell->func) { 121 ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr); 122 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 123 PetscFunctionReturn(0); 124 } 125 126 #undef __FUNCT__ 127 #define __FUNCT__ "SNESLineSearchDestroy_Shell" 128 static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 129 { 130 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 131 PetscErrorCode ierr; 132 133 PetscFunctionBegin; 134 ierr = PetscFree(shell);CHKERRQ(ierr); 135 PetscFunctionReturn(0); 136 } 137 138 #undef __FUNCT__ 139 #define __FUNCT__ "SNESLineSearchCreate_Shell" 140 /*MC 141 142 SNESLINESEARCHSHELL - Provides context for a user-provided line search routine. 143 144 The user routine has one argument, the SNESLineSearch context. The user uses the interface to 145 extract line search parameters and set them accordingly when the computation is finished. 146 147 Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 148 template in the documentation for SNESLineSearchShellSetUserFunc(). 149 150 Level: advanced 151 152 M*/ 153 PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 154 { 155 156 SNESLineSearch_Shell *shell; 157 PetscErrorCode ierr; 158 159 PetscFunctionBegin; 160 linesearch->ops->apply = SNESLineSearchApply_Shell; 161 linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 162 linesearch->ops->setfromoptions = NULL; 163 linesearch->ops->reset = NULL; 164 linesearch->ops->view = NULL; 165 linesearch->ops->setup = NULL; 166 167 ierr = PetscNewLog(linesearch,&shell);CHKERRQ(ierr); 168 169 linesearch->data = (void*) shell; 170 PetscFunctionReturn(0); 171 } 172