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, SNESLINESEARCHSHELL);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(), SNESLINESEARCHSHELL 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 60 PetscFunctionBegin; 61 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 62 ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr); 63 if (flg) { 64 shell->ctx = ctx; 65 shell->func = func; 66 } 67 PetscFunctionReturn(0); 68 } 69 70 71 #undef __FUNCT__ 72 #define __FUNCT__ "SNESLineSearchShellGetUserFunc" 73 /*@C 74 SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation. 75 76 Not Collective 77 78 Level: advanced 79 80 .keywords: SNESLineSearch, get, Shell, user, function 81 82 .seealso: SNESLineSearchShellSetUserFunc() 83 @*/ 84 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) 85 { 86 PetscErrorCode ierr; 87 PetscBool flg; 88 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 89 90 PetscFunctionBegin; 91 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 92 if (func) PetscValidPointer(func,2); 93 if (ctx) PetscValidPointer(ctx,3); 94 ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr); 95 if (flg) { 96 *ctx = shell->ctx; 97 *func = shell->func; 98 } 99 PetscFunctionReturn(0); 100 } 101 102 103 #undef __FUNCT__ 104 #define __FUNCT__ "SNESLineSearchApply_Shell" 105 static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 106 { 107 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 108 PetscErrorCode ierr; 109 110 PetscFunctionBegin; 111 112 /* apply the user function */ 113 if (shell->func) { 114 ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr); 115 } else SETERRQ(((PetscObject)linesearch)->comm, 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 = PETSC_NULL; 156 linesearch->ops->reset = PETSC_NULL; 157 linesearch->ops->view = PETSC_NULL; 158 linesearch->ops->setup = PETSC_NULL; 159 160 ierr = PetscNewLog(linesearch, SNESLineSearch_Shell, &shell);CHKERRQ(ierr); 161 linesearch->data = (void*) shell; 162 PetscFunctionReturn(0); 163 } 164