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