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 $ Vec X, Y, F, W, G; 30 $ SNES snes; 31 $ PetscFunctionBegin; 32 $ ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); 33 $ ierr = SNESLineSearchSetSuccess(linesearch, PETSC_TRUE);CHKERRQ(ierr); 34 $ ierr = SNESLineSearchGetVecs(linesearch, X, Y, F, W, G);CHKERRQ(ierr); 35 $ .. determine lambda using W and G as work vecs.. 36 $ ierr = VecAXPY(X, -lambda, Y);CHKERRQ(ierr); 37 $ ierr = SNESComputeFunction(snes, X, F);CHKERRQ(ierr); 38 $ ierr = SNESLineSearchComputeNorms(linesearch);CHKERRQ(ierr); 39 $ PetscFunctionReturn(0); 40 $ } 41 $ 42 $ ... 43 $ 44 $ ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr); 45 $ ierr = SNESLineSearchSetType(linesearch, SNES_LINESEARCH_SHELL);CHKERRQ(ierr); 46 $ ierr = SNESLineSearchShellSetUserFunc(linesearch, shellfunc, PETSC_NULL);CHKERRQ(ierr); 47 48 Level: advanced 49 50 .keywords: SNESLineSearch, Shell, user, function, set 51 52 .seealso: SNESLineSearchShellGetUserFunc(), SNES_LINESEARCH_SHELL 53 @*/ 54 PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) { 55 56 PetscErrorCode ierr; 57 PetscBool flg; 58 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 59 PetscFunctionBegin; 60 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 61 ierr = PetscTypeCompare((PetscObject)linesearch,SNES_LINESEARCH_SHELL,&flg);CHKERRQ(ierr); 62 if (flg) { 63 shell->ctx = ctx; 64 shell->func = func; 65 } 66 PetscFunctionReturn(0); 67 } 68 69 70 #undef __FUNCT__ 71 #define __FUNCT__ "SNESLineSearchShellGetUserFunc" 72 /*@C 73 SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation. 74 75 Not Collective 76 77 Level: advanced 78 79 .keywords: SNESLineSearch, get, Shell, user, function 80 81 .seealso: SNESLineSearchShellSetUserFunc() 82 @*/ 83 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) { 84 85 PetscErrorCode ierr; 86 PetscBool flg; 87 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 88 PetscFunctionBegin; 89 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 90 if (func) PetscValidPointer(func,2); 91 if (ctx) PetscValidPointer(ctx,3); 92 ierr = PetscTypeCompare((PetscObject)linesearch,SNES_LINESEARCH_SHELL,&flg);CHKERRQ(ierr); 93 if (flg) { 94 *ctx = shell->ctx; 95 *func = shell->func; 96 } 97 PetscFunctionReturn(0); 98 } 99 100 101 #undef __FUNCT__ 102 #define __FUNCT__ "SNESLineSearchApply_Shell" 103 static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 104 { 105 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 106 PetscErrorCode ierr; 107 108 PetscFunctionBegin; 109 110 /* apply the user function */ 111 if (shell->func) { 112 ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr); 113 } else { 114 SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 115 } 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 SNES_LINESEARCH_SHELL - 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 154 linesearch->ops->apply = SNESLineSearchApply_Shell; 155 linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 156 linesearch->ops->setfromoptions = PETSC_NULL; 157 linesearch->ops->reset = PETSC_NULL; 158 linesearch->ops->view = PETSC_NULL; 159 linesearch->ops->setup = PETSC_NULL; 160 161 ierr = PetscNewLog(linesearch, SNESLineSearch_Shell, &shell);CHKERRQ(ierr); 162 linesearch->data = (void*) shell; 163 PetscFunctionReturn(0); 164 } 165