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 .seealso: SNESLineSearchShellGetUserFunc(), SNESLINESEARCHSHELL 49 @*/ 50 PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) 51 { 52 PetscErrorCode ierr; 53 PetscBool flg; 54 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 55 56 PetscFunctionBegin; 57 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 58 ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr); 59 if (flg) { 60 shell->ctx = ctx; 61 shell->func = func; 62 } 63 PetscFunctionReturn(0); 64 } 65 66 /*@C 67 SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation. 68 69 Not Collective 70 71 Input Parameter: 72 . linesearch - the line search object 73 74 Output Parameters: 75 + func - the user function; can be NULL if you do not want it 76 - ctx - the user function context; can be NULL if you do not want it 77 78 Level: advanced 79 80 .seealso: SNESLineSearchShellSetUserFunc() 81 @*/ 82 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) 83 { 84 PetscErrorCode ierr; 85 PetscBool flg; 86 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 87 88 PetscFunctionBegin; 89 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 90 if (func) PetscValidPointer(func,2); 91 if (ctx) PetscValidPointer(ctx,3); 92 ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr); 93 if (flg) { 94 if (func) *func = shell->func; 95 if (ctx) *ctx = shell->ctx; 96 } 97 PetscFunctionReturn(0); 98 } 99 100 static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 101 { 102 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 103 PetscErrorCode ierr; 104 105 PetscFunctionBegin; 106 /* apply the user function */ 107 if (shell->func) { 108 ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr); 109 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 110 PetscFunctionReturn(0); 111 } 112 113 static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 114 { 115 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data; 116 PetscErrorCode ierr; 117 118 PetscFunctionBegin; 119 ierr = PetscFree(shell);CHKERRQ(ierr); 120 PetscFunctionReturn(0); 121 } 122 123 /*MC 124 SNESLINESEARCHSHELL - Provides context for a user-provided line search routine. 125 126 The user routine has one argument, the SNESLineSearch context. The user uses the interface to 127 extract line search parameters and set them accordingly when the computation is finished. 128 129 Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 130 template in the documentation for SNESLineSearchShellSetUserFunc(). 131 132 Level: advanced 133 134 M*/ 135 PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 136 { 137 138 SNESLineSearch_Shell *shell; 139 PetscErrorCode ierr; 140 141 PetscFunctionBegin; 142 linesearch->ops->apply = SNESLineSearchApply_Shell; 143 linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 144 linesearch->ops->setfromoptions = NULL; 145 linesearch->ops->reset = NULL; 146 linesearch->ops->view = NULL; 147 linesearch->ops->setup = NULL; 148 149 ierr = PetscNewLog(linesearch,&shell);CHKERRQ(ierr); 150 151 linesearch->data = (void*) shell; 152 PetscFunctionReturn(0); 153 } 154