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, PETSC_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 113 /* apply the user function */ 114 if (shell->func) { 115 ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr); 116 } else SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 117 PetscFunctionReturn(0); 118 } 119 120 #undef __FUNCT__ 121 #define __FUNCT__ "SNESLineSearchDestroy_Shell" 122 static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 123 { 124 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 125 PetscErrorCode ierr; 126 127 PetscFunctionBegin; 128 ierr = PetscFree(shell);CHKERRQ(ierr); 129 PetscFunctionReturn(0); 130 } 131 132 #undef __FUNCT__ 133 #define __FUNCT__ "SNESLineSearchCreate_Shell" 134 /*MC 135 136 SNESLINESEARCHSHELL - Provides context for a user-provided line search routine. 137 138 The user routine has one argument, the SNESLineSearch context. The user uses the interface to 139 extract line search parameters and set them accordingly when the computation is finished. 140 141 Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 142 template in the documentation for SNESLineSearchShellSetUserFunc(). 143 144 Level: advanced 145 146 M*/ 147 PETSC_EXTERN_C PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 148 { 149 150 SNESLineSearch_Shell *shell; 151 PetscErrorCode ierr; 152 153 PetscFunctionBegin; 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