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