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 = SNESLineSearchSetSuccess(linesearch, PETSC_TRUE);CHKERRQ(ierr); 35 $ ierr = SNESLineSearchGetVecs(linesearch, X, Y, F, 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 = SNESGetSNESLineSearch(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 Level: advanced 80 81 .keywords: SNESLineSearch, get, Shell, user, function 82 83 .seealso: SNESLineSearchShellSetUserFunc() 84 @*/ 85 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) 86 { 87 PetscErrorCode ierr; 88 PetscBool flg; 89 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 90 91 PetscFunctionBegin; 92 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 93 if (func) PetscValidPointer(func,2); 94 if (ctx) PetscValidPointer(ctx,3); 95 ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr); 96 if (flg) { 97 *ctx = shell->ctx; 98 *func = shell->func; 99 } 100 PetscFunctionReturn(0); 101 } 102 103 104 #undef __FUNCT__ 105 #define __FUNCT__ "SNESLineSearchApply_Shell" 106 static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 107 { 108 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 109 PetscErrorCode ierr; 110 111 PetscFunctionBegin; 112 /* apply the user function */ 113 if (shell->func) { 114 ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr); 115 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 116 PetscFunctionReturn(0); 117 } 118 119 #undef __FUNCT__ 120 #define __FUNCT__ "SNESLineSearchDestroy_Shell" 121 static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 122 { 123 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 124 PetscErrorCode ierr; 125 126 PetscFunctionBegin; 127 ierr = PetscFree(shell);CHKERRQ(ierr); 128 PetscFunctionReturn(0); 129 } 130 131 #undef __FUNCT__ 132 #define __FUNCT__ "SNESLineSearchCreate_Shell" 133 /*MC 134 135 SNESLINESEARCHSHELL - Provides context for a user-provided line search routine. 136 137 The user routine has one argument, the SNESLineSearch context. The user uses the interface to 138 extract line search parameters and set them accordingly when the computation is finished. 139 140 Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 141 template in the documentation for SNESLineSearchShellSetUserFunc(). 142 143 Level: advanced 144 145 M*/ 146 PETSC_EXTERN_C PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 147 { 148 149 SNESLineSearch_Shell *shell; 150 PetscErrorCode ierr; 151 152 PetscFunctionBegin; 153 linesearch->ops->apply = SNESLineSearchApply_Shell; 154 linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 155 linesearch->ops->setfromoptions = NULL; 156 linesearch->ops->reset = NULL; 157 linesearch->ops->view = NULL; 158 linesearch->ops->setup = NULL; 159 160 ierr = PetscNewLog(linesearch, SNESLineSearch_Shell, &shell);CHKERRQ(ierr); 161 162 linesearch->data = (void*) shell; 163 PetscFunctionReturn(0); 164 } 165