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 19cd7522eaSPeter Brune Calling sequence of func: 20cd7522eaSPeter Brune + linesearch - the linesearch instance 21cd7522eaSPeter Brune - ctx - the above mentioned context 22cd7522eaSPeter Brune 23cd7522eaSPeter Brune Usage: 24a6dfd86eSKarl Rupp $ PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx) 25a6dfd86eSKarl Rupp $ { 2678bcb3b5SPeter Brune $ Vec X,Y,F,W,G; 2778bcb3b5SPeter Brune $ SNES snes; 28cd7522eaSPeter Brune $ PetscFunctionBegin; 299566063dSJacob Faibussowitsch $ PetscCall(SNESLineSearchGetSNES(linesearch,&snes)); 309566063dSJacob Faibussowitsch $ PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED)); 319566063dSJacob Faibussowitsch $ PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G)); 3278bcb3b5SPeter Brune $ .. determine lambda using W and G as work vecs.. 339566063dSJacob Faibussowitsch $ PetscCall(VecAXPY(X,-lambda,Y)); 349566063dSJacob Faibussowitsch $ PetscCall(SNESComputeFunction(snes,X,F)); 359566063dSJacob Faibussowitsch $ PetscCall(SNESLineSearchComputeNorms(linesearch)); 36*3ba16761SJacob Faibussowitsch $ PetscFunctionReturn(PETSC_SUCCESS); 37cd7522eaSPeter Brune $ } 38cd7522eaSPeter Brune $ 39cd7522eaSPeter Brune $ ... 40cd7522eaSPeter Brune $ 419566063dSJacob Faibussowitsch $ PetscCall(SNESGetLineSearch(snes, &linesearch)); 429566063dSJacob Faibussowitsch $ PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL)); 439566063dSJacob Faibussowitsch $ PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL)); 44cd7522eaSPeter Brune 45f40b411bSPeter Brune Level: advanced 46f40b411bSPeter Brune 47f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch` 48f40b411bSPeter Brune @*/ 49d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) 50d71ae5a4SJacob Faibussowitsch { 516a388c36SPeter Brune PetscBool flg; 52f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 530adebc6cSBarry Smith 546a388c36SPeter Brune PetscFunctionBegin; 55f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 569566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 576a388c36SPeter Brune if (flg) { 586a388c36SPeter Brune shell->ctx = ctx; 599e764e56SPeter Brune shell->func = func; 606a388c36SPeter Brune } 61*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 626a388c36SPeter Brune } 636a388c36SPeter Brune 64f40b411bSPeter Brune /*@C 65f6dfbefdSBarry Smith SNESLineSearchShellGetUserFunc - Gets the user function and context for the `SNESLINESEARCHSHELL` 66f40b411bSPeter Brune 67f40b411bSPeter Brune Not Collective 68f40b411bSPeter Brune 694a2f8832SBarry Smith Input Parameter: 704a2f8832SBarry Smith . linesearch - the line search object 714a2f8832SBarry Smith 724a2f8832SBarry Smith Output Parameters: 734a2f8832SBarry Smith + func - the user function; can be NULL if you do not want it 744a2f8832SBarry Smith - ctx - the user function context; can be NULL if you do not want it 754a2f8832SBarry Smith 76f40b411bSPeter Brune Level: advanced 77f40b411bSPeter Brune 78f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch` 79f40b411bSPeter Brune @*/ 80d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) 81d71ae5a4SJacob Faibussowitsch { 826a388c36SPeter Brune PetscBool flg; 83f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 840adebc6cSBarry Smith 856a388c36SPeter Brune PetscFunctionBegin; 86f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1); 876a388c36SPeter Brune if (func) PetscValidPointer(func, 2); 886a388c36SPeter Brune if (ctx) PetscValidPointer(ctx, 3); 899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg)); 906a388c36SPeter Brune if (flg) { 914a2f8832SBarry Smith if (func) *func = shell->func; 924a2f8832SBarry Smith if (ctx) *ctx = shell->ctx; 936a388c36SPeter Brune } 94*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 956a388c36SPeter Brune } 966a388c36SPeter Brune 97d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) 98d71ae5a4SJacob Faibussowitsch { 99f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1006a388c36SPeter Brune 1016a388c36SPeter Brune PetscFunctionBegin; 1026a388c36SPeter Brune /* apply the user function */ 1036a388c36SPeter Brune if (shell->func) { 1049566063dSJacob Faibussowitsch PetscCall((*shell->func)(linesearch, shell->ctx)); 105ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc"); 106*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1076a388c36SPeter Brune } 1086a388c36SPeter Brune 109d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) 110d71ae5a4SJacob Faibussowitsch { 111f1c6b773SPeter Brune SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data; 1126a388c36SPeter Brune 1136a388c36SPeter Brune PetscFunctionBegin; 1149566063dSJacob Faibussowitsch PetscCall(PetscFree(shell)); 115*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1166a388c36SPeter Brune } 1176a388c36SPeter Brune 118954494b2SJed Brown /*MC 1191a4f838cSPeter Brune SNESLINESEARCHSHELL - Provides context for a user-provided line search routine. 120954494b2SJed Brown 121f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context. The user uses the interface to 122954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished. 123954494b2SJed Brown 124cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done. There is also a basic 125cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc(). 126954494b2SJed Brown 127954494b2SJed Brown Level: advanced 128954494b2SJed Brown 129f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()` 130954494b2SJed Brown M*/ 131d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) 132d71ae5a4SJacob Faibussowitsch { 133f1c6b773SPeter Brune SNESLineSearch_Shell *shell; 1346a388c36SPeter Brune 1356a388c36SPeter Brune PetscFunctionBegin; 136f1c6b773SPeter Brune linesearch->ops->apply = SNESLineSearchApply_Shell; 137f1c6b773SPeter Brune linesearch->ops->destroy = SNESLineSearchDestroy_Shell; 1380298fd71SBarry Smith linesearch->ops->setfromoptions = NULL; 1390298fd71SBarry Smith linesearch->ops->reset = NULL; 1400298fd71SBarry Smith linesearch->ops->view = NULL; 1410298fd71SBarry Smith linesearch->ops->setup = NULL; 1426a388c36SPeter Brune 1434dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&shell)); 144f5af7f23SKarl Rupp 1456a388c36SPeter Brune linesearch->data = (void *)shell; 146*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1476a388c36SPeter Brune } 148