1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h> 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> 36a388c36SPeter Brune 46a388c36SPeter Brune typedef struct { 5f1c6b773SPeter Brune SNESLineSearchUserFunc func; 66a388c36SPeter Brune void *ctx; 7f1c6b773SPeter Brune } SNESLineSearch_Shell; 86a388c36SPeter Brune 9f40b411bSPeter Brune /*@C 10f6dfbefdSBarry Smith SNESLineSearchShellSetUserFunc - Sets the user function for the `SNESLINESEARCHSHELL` implementation. 11f40b411bSPeter Brune 12f40b411bSPeter Brune Not Collective 13f40b411bSPeter Brune 14cd7522eaSPeter Brune Input Parameters: 15f6dfbefdSBarry Smith + linesearch - `SNESLineSearch` context 16cd7522eaSPeter Brune . func - function implementing the linesearch shell. 17cd7522eaSPeter Brune - ctx - context for func 18cd7522eaSPeter Brune 19*20f4b53cSBarry Smith Calling sequence of `func`: 20*20f4b53cSBarry Smith $ PetscErrorCode func(SNESLinesearch, void *ctx) 21cd7522eaSPeter Brune + linesearch - the linesearch instance 22cd7522eaSPeter Brune - ctx - the above mentioned context 23cd7522eaSPeter Brune 24cd7522eaSPeter Brune Usage: 25*20f4b53cSBarry Smith .vb 26*20f4b53cSBarry Smith PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx) 27*20f4b53cSBarry Smith { 28*20f4b53cSBarry Smith Vec X,Y,F,W,G; 29*20f4b53cSBarry Smith SNES snes; 30*20f4b53cSBarry Smith PetscFunctionBegin; 31*20f4b53cSBarry Smith PetscCall(SNESLineSearchGetSNES(linesearch,&snes)); 32*20f4b53cSBarry Smith PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED)); 33*20f4b53cSBarry Smith PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G)); 34*20f4b53cSBarry Smith .. determine lambda using W and G as work vecs.. 35*20f4b53cSBarry Smith PetscCall(VecAXPY(X,-lambda,Y)); 36*20f4b53cSBarry Smith PetscCall(SNESComputeFunction(snes,X,F)); 37*20f4b53cSBarry Smith PetscCall(SNESLineSearchComputeNorms(linesearch)); 38*20f4b53cSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 39*20f4b53cSBarry Smith } 40*20f4b53cSBarry Smith 41*20f4b53cSBarry Smith ... 42*20f4b53cSBarry Smith 43*20f4b53cSBarry Smith PetscCall(SNESGetLineSearch(snes, &linesearch)); 44*20f4b53cSBarry Smith PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL)); 45*20f4b53cSBarry Smith PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL)); 46*20f4b53cSBarry Smith .ve 47cd7522eaSPeter Brune 48f40b411bSPeter Brune Level: advanced 49f40b411bSPeter Brune 50f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch` 51f40b411bSPeter Brune @*/ 52d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) 53d71ae5a4SJacob Faibussowitsch { 546a388c36SPeter Brune PetscBool flg; 55f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 560adebc6cSBarry Smith 576a388c36SPeter Brune PetscFunctionBegin; 58f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 599566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 606a388c36SPeter Brune if (flg) { 616a388c36SPeter Brune shell->ctx = ctx; 629e764e56SPeter Brune shell->func = func; 636a388c36SPeter Brune } 643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 656a388c36SPeter Brune } 666a388c36SPeter Brune 67f40b411bSPeter Brune /*@C 68f6dfbefdSBarry Smith SNESLineSearchShellGetUserFunc - Gets the user function and context for the `SNESLINESEARCHSHELL` 69f40b411bSPeter Brune 70f40b411bSPeter Brune Not Collective 71f40b411bSPeter Brune 724a2f8832SBarry Smith Input Parameter: 734a2f8832SBarry Smith . linesearch - the line search object 744a2f8832SBarry Smith 754a2f8832SBarry Smith Output Parameters: 764a2f8832SBarry Smith + func - the user function; can be NULL if you do not want it 774a2f8832SBarry Smith - ctx - the user function context; can be NULL if you do not want it 784a2f8832SBarry Smith 79f40b411bSPeter Brune Level: advanced 80f40b411bSPeter Brune 81f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch` 82f40b411bSPeter Brune @*/ 83d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) 84d71ae5a4SJacob Faibussowitsch { 856a388c36SPeter Brune PetscBool flg; 86f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 870adebc6cSBarry Smith 886a388c36SPeter Brune PetscFunctionBegin; 89f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 906a388c36SPeter Brune if (func) PetscValidPointer(func, 2); 916a388c36SPeter Brune if (ctx) PetscValidPointer(ctx, 3); 929566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 936a388c36SPeter Brune if (flg) { 944a2f8832SBarry Smith if (func) *func = shell->func; 954a2f8832SBarry Smith if (ctx) *ctx = shell->ctx; 966a388c36SPeter Brune } 973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 986a388c36SPeter Brune } 996a388c36SPeter Brune 100d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 101d71ae5a4SJacob Faibussowitsch { 102f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1036a388c36SPeter Brune 1046a388c36SPeter Brune PetscFunctionBegin; 1056a388c36SPeter Brune /* apply the user function */ 1066a388c36SPeter Brune if (shell->func) { 1079566063dSJacob Faibussowitsch PetscCall((*shell->func)(linesearch, shell->ctx)); 108ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 1093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1106a388c36SPeter Brune } 1116a388c36SPeter Brune 112d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 113d71ae5a4SJacob Faibussowitsch { 114f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1156a388c36SPeter Brune 1166a388c36SPeter Brune PetscFunctionBegin; 1179566063dSJacob Faibussowitsch PetscCall(PetscFree(shell)); 1183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1196a388c36SPeter Brune } 1206a388c36SPeter Brune 121954494b2SJed Brown /*MC 1221a4f838cSPeter Brune SNESLINESEARCHSHELL - Provides context for a user-provided line search routine. 123954494b2SJed Brown 124f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context. The user uses the interface to 125954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished. 126954494b2SJed Brown 127cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 128cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc(). 129954494b2SJed Brown 130954494b2SJed Brown Level: advanced 131954494b2SJed Brown 132f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()` 133954494b2SJed Brown M*/ 134d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 135d71ae5a4SJacob Faibussowitsch { 136f1c6b773SPeter Brune SNESLineSearch_Shell *shell; 1376a388c36SPeter Brune 1386a388c36SPeter Brune PetscFunctionBegin; 139f1c6b773SPeter Brune linesearch->ops->apply = SNESLineSearchApply_Shell; 140f1c6b773SPeter Brune linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 1410298fd71SBarry Smith linesearch->ops->setfromoptions = NULL; 1420298fd71SBarry Smith linesearch->ops->reset = NULL; 1430298fd71SBarry Smith linesearch->ops->view = NULL; 1440298fd71SBarry Smith linesearch->ops->setup = NULL; 1456a388c36SPeter Brune 1464dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&shell)); 147f5af7f23SKarl Rupp 1486a388c36SPeter Brune linesearch->data = (void *)shell; 1493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1506a388c36SPeter Brune } 151